1

I'm trying to write a for loop in my enemy class to check collision with the player...What I'm trying to do specifically is have it check each pixel in every row, so it should check all in a row then go to the next row. I'm having trouble figuring out how to write it so it checks every row...How would I do this? Here is what I've written...I'm pretty sure I need to have another for loop in there to go down each row, but I'm not sure how to implement it.

bool Enemy::checkCollision()
{
    for(i = 0; i < postion.w; i++)
    {
        if(position.x + i == player.position.x)
        {
            return true;
        }
        else if(position.y + i == player.position.y)
        {
            return true;
        }
        else
        { 
            return false; 
        }
    }
}
user1122136
  • 98
  • 2
  • 8
  • possible duplicate of [2D Platformer Collision Problems With Both Axes](http://stackoverflow.com/questions/2656943/2d-platformer-collision-problems-with-both-axes) – ChrisBD Jan 03 '12 at 09:20
  • How do you store pixel data? Is it a vector, plain array, 2d array...? – jrok Jan 03 '12 at 09:26
  • Not sure exactly what you mean by "pixel data"...But I use SDL_Rect for the positions. http://sdl.beuc.net/sdl.wiki/SDL_Rect – user1122136 Jan 03 '12 at 09:45

2 Answers2

3

Waaaay to complicated. Have a free function which takes in two positions and two collision boxes and just use a simple check (concise version at the bottom, this one explains how it works):

// y ^
//   |
//   +----> x
struct SDL_Rect{
    unsigned x, y;
    int w, h;
};

bool collides(SDL_Rect const& o1, SDL_Rect const& o2){
  /* y_max -> +------------+
   *          |            |
   *          |            |
   *          +------------+ <- x_max
   *    |-----^------|
   *     y_min, x_min        
   */
  unsigned o1_x_min = o1.x, o1_x_max = o1.x + o1.w;
  unsigned o2_x_min = o2.x, o2_x_max = o2.x + o2.w;

  /* Collision on X axis: o1_x_max > o2_x_min && o1_x_min < o2_x_max
   * o1_x_min -> +-----------+ <- o1_x_max
   *     o2_x_min -> +-------------+ <- o2_x_max
   *
   * No collision 1: o1_x_max < o2_x_min
   * o1_x_min -> +-----------+ <- o1_x_max
   *                  o2_x_min -> +-------------+ <- o2_x_max
   *
   * No collision 2: o1_x_min > o2_x_max
   *                  o1_x_min -> +-------------+ <- o1_x_max
   * o2_x_min -> +-----------+ <- o2_x_max
   */
  if(o1_x_max >= o2_x_min && o1_x_min <= o2_x_max)
  { // collision on X, check Y
    /* Collision on Y axis: o1_y_max > o2_y_min && o1_y_min < o2_y_max
     * o1_y_max -> +
     *             |  + <- o2_y_max
     *             |  |
     * o1_y_min -> +  |
     *                + <- o2_y_min
     * No collision: o1_y_min > o2_y_max
     * o1_y_max -> +
     *             | 
     *             | 
     * o1_y_min -> +
     *                + <- o2_y_max
     *                |
     *                |
     *                + <- o2_y_min
     */
    unsigned o1_y_min = o1.y, o1_y_max = o1.y + o1.h;
    unsigned o2_y_min = o2.y, o2_y_max = o2.y + o2.h;
    return o1_y_max >= o2_y_min && o1_y_min <= o2_y_max;
  }
  return false;
}

Concise version of collides:

bool collides(SDL_Rect const& o1, SDL_Rect const& o2){
  unsigned o1_x_min = o1.x, o1_x_max = o1.x + o1.w;
  unsigned o2_x_min = o2.x, o2_x_max = o2.x + o2.w;

  if(o1_x_max >= o2_x_min && o1_x_min <= o2_x_max)
  { // collision on X, check Y
    unsigned o1_y_min = o1.y, o1_y_max = o1.y + o1.h;
    unsigned o2_y_min = o2.y, o2_y_max = o2.y + o2.h;
    return o1_y_max >= o2_y_min && o1_y_min <= o2_y_max;
  }
  return false;
}
Xeo
  • 129,499
  • 52
  • 291
  • 397
  • Alright...I understand this code for the most part...But what exactly goes into the parameters? Also, I don't understand exactly what it's returning if collision is detected...I'd expect it to return true. – user1122136 Jan 03 '12 at 10:24
  • @user: In goes the SDL_Rect that contains the position and the bounds of the objects to test. `collides(enemy[i].rect, player.rect)` for example. Out comes `true` if you collide on both axes, `false` if you collide on neither or only on one. The `return condition_one && condition_two;` is a shorthand for `if(condition_one && condition_two) return true; else return false;`. – Xeo Jan 03 '12 at 10:27
  • Alright...I think I get it...If not, I'll figure it out. Thank you for your help... – user1122136 Jan 03 '12 at 10:28
0

SDL_Collide will do pixel-perfect collision detection.

genpfault
  • 51,148
  • 11
  • 85
  • 139