# mental problem

• 12-14-2005
mental problem
for whatever reason I can't figure this out
I'm using some code from gamedev for 2d pixel perfect collision detection, it looks like this now
Code:

```bool CollideYou(int index) {         int left1, left2;         int right1, right2;         int top1, top2;         int bottom1, bottom2;     left1 = BulletsE[index].x;     left2 = You.x;     right1 = BulletsE[index].x + 5;     right2 = You.x + 99;     top1 = BulletsE[index].y;     top2 = You.y;     bottom1 = BulletsE[index].y + 20;     bottom2 = You.y + 75;     if (bottom1 < top2) return false;     if (top1 > bottom2) return false;     if (right1 < left2) return false;     if (left1 > right2) return false;         int over_bottom, over_top, over_right, over_left;             if (bottom1 > bottom2) over_bottom = bottom2;     else over_bottom = bottom1;     if (top1 < top2) over_top = top2;     else over_top = top1;     if (right1 > right2) over_right = right2;     else over_right = right1;     if (left1 < left2) over_left = left2;     else over_left = left1;         for (int z = over_bottom; z <= over_top; z++)         {                 for (int y = over_left; y <= over_right; y++)                 {                 }         }         return false; }```
The problem is I can't figure out how to convert z and y in the for loops into actual x's and y's for the two SDL surfaces I'm colliding (ship and bullet)

Thanks,
MC
• 12-19-2005
After a break, I started working on this again and all it seems to be doing is checking for a rectangle collision. The per pixel part seems to be always returning false, and I can't figure out why. Here's the updated code...

Code:

```bool CollideYou(int index) {         int left1, left2;         int right1, right2;         int top1, top2;         int bottom1, bottom2;     left1 = BulletsE[index].x;     left2 = You.x;     right1 = BulletsE[index].x + 5;     right2 = You.x + 99;     top1 = BulletsE[index].y;     top2 = You.y;     bottom1 = BulletsE[index].y + 20;     bottom2 = You.y + 75; //The basic rectangle collision, seems to be working fine     if (bottom1 < top2) return false;     if (top1 > bottom2) return false;     if (right1 < left2) return false;     if (left1 > right2) return false;         int over_bottom, over_top, over_right, over_left;             if (bottom1 > bottom2) over_bottom = bottom2;     else over_bottom = bottom1;     if (top1 < top2) over_top = top2;     else over_top = top1;     if (right1 > right2) over_right = right2;     else over_right = right1;     if (left1 < left2) over_left = left2;     else over_left = left1; //This should be giving me pixel perfect 2D collision detection, but //it's not         int offset1, offset2;         offset1 = ((over_top - You.y) * 99) + over_left;         offset2 = ((over_top - MasterList[index].y) * 5) + over_left;         for (int y = 0; y <= over_bottom-over_top; y++)         {                 for (int x = 0; x <= over_right-over_left; x++)                 {                         if ((!IsPink(ship, x+offset1, y)) && (!IsPink(bulletE, x+offset2, y)))                                 return true;                 }         }         return false; }```
And just incase this has an error
Code:

```bool IsPink(SDL_Surface *surface, int x, int y) {   Uint32 color = SDL_MapRGB(screen->format, 255, 0, 255);   switch (screen->format->BytesPerPixel)   {     case 1:         Uint8 *bufp;         bufp = (Uint8 *)surface->pixels + y*surface->pitch + x;                 if (*bufp == color)                         return true;                 break;     case 2:         Uint16 *bufp1;         bufp1 = (Uint16 *)surface->pixels + y*surface->pitch/2 + x;                 if (*bufp1 == color)                         return true;                 break;     case 4:         Uint32 *bufp2;         bufp2 = (Uint32 *)surface->pixels + y*surface->pitch/4 + x;                 if (*bufp2 == color)                         return true;                 break;   }   return false; }```
Thanks a bunch
• 12-19-2005
prog-bman
Hey madcow this is from my game with allegro. I am sure it can be conerted to SDL fairly easily.
Code:

```bool Sprite::operator== (Sprite &hit) {     //Make sure we are working with the latest info     Update_Collision();     hit.Update_Collision();                     int this_x_offset, this_y_offset, hit_x_offset,hit_y_offset;         int overlap_width,overlap_height;             //loop counters         int height_count = 0, width_count = 0;                 //hold integer rep of pixels         int this_pixel;         int hit_pixel;                 //Hold bitmask color of each image         int this_bitmask  = bitmap_mask_color(image);         int hit_bitmask = bitmap_mask_color(hit.image);         //check if ships is alive         if(isAlive == false || hit.isAlive == false)         {                 return false; //no collision if one dead     }             //check bounding box         if(left > hit.right)                 return false;         if(right < hit.left)                 return false;                 if(bottom < hit.top)                 return false;         if(top > hit.bottom)                 return false;         //bounding box test passed there is intersection         //check overlap                 //find x overlap         if(xPos < hit.xPos) //this left of hit         {                 this_x_offset = hit.xPos - xPos;                 hit_x_offset = 0;                 overlap_width = image->w - this_x_offset;                }                 //else offset is xPos - hit.xPos;         else //this right of hit         {                 hit_x_offset = xPos - hit.xPos;                 this_x_offset = 0;                 //get overlap width                 overlap_width = hit.image->w - hit_x_offset;         }         //find y overlap         if(yPos < hit.yPos) //this above is hit         {                 this_y_offset = hit.yPos - yPos;                 hit_y_offset = 0;                 //get overlap height                 overlap_height = (image->h - this_y_offset);         }         //else offset is yPos - hit.yPos;         else //this below hit         {                 this_y_offset = 0;                 hit_y_offset = yPos - hit.yPos;                                 //get overlap height                 overlap_height = (hit.image->h - hit_y_offset);         }         //now that overlap box has been calculated we will check each pixel in the box                 while(height_count < overlap_height) //check a line loop         {                 while(width_count < overlap_width) //check pixel loop                 {                         //get pixel data for this                         this_pixel = getpixel(image,this_x_offset+width_count,height_count+this_y_offset);                                                                        //get pixel data for hit                         hit_pixel = getpixel(hit.image,hit_x_offset+width_count,height_count+hit_y_offset);                                                        //check to see if both are transparent                         if( (this_pixel  != this_bitmask && this_pixel  != -1) &&                                 (hit_pixel != hit_bitmask && hit_pixel != -1)) //if both opaque return true                         {                                 return true;                         }                         //else                         width_count++; //incrment pixel                 }                                width_count = 0; //reset pixel counter                 height_count++; //increment line         }         return false; //no collision return false }```
• 12-19-2005
Thanks alot prog-bman, that should be easy to convert
• 12-19-2005
prog-bman
Now I am not sure how fast this is or how efficent the checks are but I do know that it works :)
• 12-20-2005
VirtualAce
There is no way either of those are pixel-perfect. Pixel-perfect would be based on time intervals and not coordinates. Coordinates can fly through one another. You must break the interval down into smaller intervals and then integrate over time to find out the exact moment of impact.

But for 2D, this would prob work well enough. But I do recommend checking out the moving bounding box intersection test.
• 12-20-2005
prog-bman
Quote:

Originally Posted by Bubba
There is no way either of those are pixel-perfect. Pixel-perfect would be based on time intervals and not coordinates. Coordinates can fly through one another. You must break the interval down into smaller intervals and then integrate over time to find out the exact moment of impact.

But for 2D, this would prob work well enough. But I do recommend checking out the moving bounding box intersection test.

I am confused Bubba, This does collision detection based on a pixel that is not the mask, so if two pixels in two different objects that are not a mask are overlapping in a set x,y coord(pixel) there is a collision. What does time have to do with any of this?
• 12-20-2005
CornedBee
What it has to do is that time in any game flows in discrete steps, usually called frames, due to the nature of computers. This means that there is a point in time A and a point in time B, and in-between there's nothing.

Now, if an object is fast enough, it might move more than one pixel each interval. For simplicity's sake, let's assume a 1-dimensional display. Object X has an x-coordinate of 100 and a speed of +4px/frame. Object Y has an x-coordinate of 123 and a speed of -3px/frame.
As can easily be calculated, the coodinates change like thus:
1 frame: 104 / 120
2 frames: 108 / 117
3 frames: 112 / 114
4 frames: 116 / 111

Note that
1) if the objects are small enough, they might pass through each other completely undetected.
2) Even if they aren't, the collision is inaccurate. Where exactly did they collide? Without looking at your algorithm, it might be anywhere between 111 and 116. And when? If the collision is perfectly elastic (e.g. a pool billard simulator would depend on this), you'd have to note that, given that the two objects are approaching each other at 7px/frame and are only 2px apart after 3 frames, they'd collide after 2 7ths of the 4th frame and would spend the other 5 7ths moving apart again, during which time X would move (assuming X and Y have equal mass) ~2px to the left, while Y moves ~3 px to the right.

For these reasons, it is necessary that you do more advanced calculations to know exactly where an object should be.
This accuracy might not be necessary for your game. But your algorithms won't be pixel perfect without it.
• 12-21-2005
prog-bman
Well now I see :). Thanks CornedBee.