int CWaterPolo::CheckCollision ( CPlayer *Player, CObject *Object )
{
// DDSURFACEDESC TO GET PITCH WHEN I LOCK SURFACE
DDSURFACEDESC2 ddsdBlank;
DDRAW_INIT_STRUCT(ddsdBlank);
// RECTS FOR BOUNDING BXES
RECT rOne, rTwo, rOverlap;
RECT rOneOverlap, rTwoOverlap;
// WIDHT AND HEIGHT OF OVERLAP
int overlapWidth, overlapHeight;
// LOOP VARS
int i, j;
// PIXELS FOR SURFACES
UINT *pixel1, *pixel2;
// USING THIS TO CHEAT OUT OF THE LOOP
bool iscollision = false;
// WIDTH OF BITMAPS
int oneWidth, twoWidth;
// USED FOR MAKING THE CODE A LITTLE EASIER TO READ
// X AND Y POSITIONS
int onex;
int oney;
int twox;
int twoy;
// THE COLOR KEY
UINT ColorKey = _RGB16BIT565(255, 0, 255);
// FILL IN COMPARISON RECTS
rOne.left = Player->GetX();
rTwo.left = Object->GetX();
rOne.right = Player->GetX() + Player->CurrBitmap->GetWidth();
rTwo.right = Object->GetX() + Object->GetWidth();
rOne.top = Player->GetY();
rTwo.top = Object->GetY();
rOne.bottom = Player->GetY() + Player->CurrBitmap->GetHeight();
rTwo.bottom = Object->GetY() + Object->GetHeight();
// TEST IF THE BOUNDING BOXES INTERSECT
if (IntersectRect(&rOverlap, &rOne, &rTwo))
{
// FILL IN OVERLAP RECTANGLE INFORMATION
// FIRST ONE
rOneOverlap.top = rOverlap.top - rOne.top;
rOneOverlap.bottom = rOverlap.bottom - rOne.top;
rOneOverlap.left = rOverlap.left - rOne.left;
rOneOverlap.right = rOverlap.right - rOne.left;
// SECOND ONE
rTwoOverlap.top = rOverlap.top - rTwo.top;
rTwoOverlap.bottom = rOverlap.bottom - rTwo.top;
rTwoOverlap.left = rOverlap.left - rTwo.left;
rTwoOverlap.right = rOverlap.right - rTwo.left;
// FILL IN WIDTH AND HEIGHT OF OVERLAPPING AREA
overlapWidth = rOverlap.right - rOverlap.left - 1;
overlapHeight = rOverlap.bottom - rOverlap.top - 1;
// LOCK SURFACES AND GET THEIR PITCH AND SURFACE
// LOCK SURFACE ONE
surfaceone = Player->CurrBitmap->GetSurface();
surfaceone->Lock(&rOneOverlap, &ddsdBlank, DDLOCK_WAIT | DDLOCK_READONLY, 0);
pixel1 = (UINT *)ddsdBlank.lpSurface;
int oneWidth = ddsdBlank.lPitch;
// LOCK SURFACE TWO
surfacetwo = Object->GetSurface();
DDraw->GetSurface(BACK_BUFFER)->Blt(&temp, surfacetwo, &rTwoOverlap, DDBLT_WAIT | DDBLT_KEYSRC, 0);
surfacetwo->Lock(&rTwoOverlap, &ddsdBlank, DDLOCK_WAIT | DDLOCK_READONLY, 0);
pixel2 = (UINT *)ddsdBlank.lpSurface;
twoWidth = ddsdBlank.lPitch;
// LOOP THROUGH AND COMPARE THEIR PIXEL VALUES TO THE COLORKEY
for (i = 0; i < overlapWidth; i++)
{
for (j = 0; j < overlapHeight; j++)
{
if (pixel1[i + onex + (j + oney) * oneWidth] != ColorKey
&& pixel2[i + twox + (j + twoy) * twoWidth] != ColorKey)
{
Console.AddMessage("Collision occurred!");
iscollision = true;
break;
}
}
if (iscollision)
break;
}
// UNLOCK THE SURFACES
surfaceone->Unlock(&rOneOverlap);
surfacetwo->Unlock(&rTwoOverlap);
// THERE IS A COLLISION
if (iscollision)
return 1;
}
// NO COLLISION!
return 0;
}
pixel collision detection help
I think I did this right, but I'm not sure... it's reporting a collision at the first time it runs through the loop.
OK I AM PUTTING COMMENTS IN FOR MR. I'M TOO GOOD FOR MYSELF.
(pardon my debug/test/console stuff)
What am I doing wrong? I can see it's checking the correct RECTs and stuff, but it returns the first time through the loop! Help!
[edited by - apollyon on June 9, 2002 5:19:26 PM]
[edited by - apollyon on June 10, 2002 6:28:36 PM]
I don''t think I''m going to waste my time trudging though all that code with out any comments, spaces between the lines, and hardly any modularity.
It will make your life (and others looking at your code) much easier if you add comments while you write, declare all variables at the top of the function (or block atleast), and have some spaces between lines for God''s sake.
Other than that, this problem is a simple logic problem which you should solve yourself instead of asking us to do your work for you.
Breakpoints, Breakpoints, and more Breakpoints.
Nutts
It will make your life (and others looking at your code) much easier if you add comments while you write, declare all variables at the top of the function (or block atleast), and have some spaces between lines for God''s sake.
Other than that, this problem is a simple logic problem which you should solve yourself instead of asking us to do your work for you.
Breakpoints, Breakpoints, and more Breakpoints.
Nutts
Um, yeah, I explained that it the first time it goes through the loop it kills itself. Maybe you should learn to read, moron. I apologize for the lack of comments, but that''s not the case. I determined what the problem is, and I don''t know how to go about fixing it. When I compare the pixel to the color key, it automatically says it''s the same. The hostility you''ve expressed does wonders for your character, dude. You could''ve at least attempted to read it.
Wasn''t trying to be hostile, but when you offer up code for people to debug for you, you should try and make it as easy as possible for them to do so.
Besides, I really don''t have the time to look through your code and debug it for you. I can offer 1 suggestion (I''ve done pixel-per-pixel collision too): Don''t Lock and Unlock the surface, it''s too slow. Instead, store seperate masks for each image with one bit-per-pixel. It will do wonders for your speed.
Besides, I really don''t have the time to look through your code and debug it for you. I can offer 1 suggestion (I''ve done pixel-per-pixel collision too): Don''t Lock and Unlock the surface, it''s too slow. Instead, store seperate masks for each image with one bit-per-pixel. It will do wonders for your speed.
Some pixel collision stuff
Bits and pieces from my sprite engine ( 16 bit stuff ).
_____________________________________________________________
// make an array to hold the bitmask
BOOL *source_bitmask;
source_bitmask = new BOOL [ surface_width * surface_height ];
_____________________________________________________________
We have to set up a bitmask for the surface.
The pixel data will be copied onto the above array as BOOL.
_____________________________________________________________
Now we have to test for a collision
I made this a global fuction and made it a friend to my sprite class. This is rather bulky code, but it was written for animated and non-animated sprites. I hope you can follow it.
Well that''s how I did it. I re-wrote John Amatos collision algos with bitmasks. If find the collision detection rather quick.
Guy
Bits and pieces from my sprite engine ( 16 bit stuff ).
_____________________________________________________________
// make an array to hold the bitmask
BOOL *source_bitmask;
source_bitmask = new BOOL [ surface_width * surface_height ];
_____________________________________________________________
We have to set up a bitmask for the surface.
The pixel data will be copied onto the above array as BOOL.
void SPRITE::Load_Bitmask(){ int fb_cnt = 0; USHORT *surf_ptr; // A pointer to the surface DDSURFACEDESC2 ddsd; ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2)); ddsd.dwSize = sizeof(ddsd); // Load size // Lock the surface ( surface ) -> Lock( NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); // Get a pointer to surface surf_ptr = (USHORT *)ddsd.lpSurface; // Load the bitmask looping through the surface for ( DWORD i = 0 ; i < surface_height ; i++ ) { for ( DWORD j = 0 ; j < surface_width ; j++ ) { // Calculate position in array fb_cnt = ( ( i * surface_width ) + j ); // If the value is not 0, set the BOOL to TRUE source_bitmask [ fb_cnt ] = ( *surf_ptr != 0 ) ? TRUE : FALSE; // Increment the surface pointer surf_ptr++; } } // Unlock the surface ( surface ) -> Unlock(NULL);}// end Load_Bitmask
_____________________________________________________________
Now we have to test for a collision
I made this a global fuction and made it a friend to my sprite class. This is rather bulky code, but it was written for animated and non-animated sprites. I hope you can follow it.
short int Sprite_Sprite_Collide( SPRITE *ptr_1, SPRITE *ptr_2 ){ int sp_width_1 = ptr_1 -> width; int sp_width_2 = ptr_2 -> width; RECT frame_1, frame_2; int frame_offset_1, frame_offset_2; int over_left, over_right; int over_top, over_bottom;; int over_width,over_height; int i, j; int y1_offset, y2_offset; BOOL *P_p1, *P_p2; // Quick Reject Stuff if ( ptr_1 -> dest_rect.bottom < ptr_2 -> dest_rect.top ) return(0); if ( ptr_1 -> dest_rect.top > ptr_2 -> dest_rect.bottom ) return(0); if ( ptr_1 -> dest_rect.right < ptr_2 -> dest_rect.left ) return(0); if ( ptr_1 -> dest_rect.left > ptr_2 -> dest_rect.right ) return(0); // Get the overlapping rectangle if ( ptr_1 -> dest_rect.bottom > ptr_2 -> dest_rect.bottom ) over_bottom = ptr_2 -> dest_rect.bottom; else over_bottom = ptr_1 -> dest_rect.bottom; if ( ptr_1 -> dest_rect.top < ptr_2 -> dest_rect.top ) over_top = ptr_2 -> dest_rect.top; else over_top = ptr_1 -> dest_rect.top; if ( ptr_1 -> dest_rect.right > ptr_2 -> dest_rect.right ) over_right = ptr_2 -> dest_rect.right; else over_right = ptr_1 -> dest_rect.right; if ( ptr_1 -> dest_rect.left < ptr_2 -> dest_rect.left ) over_left = ptr_2 -> dest_rect.left; else over_left = ptr_1 -> dest_rect.left; // Calculate frame offsets for object 1 frame_1.left = ( over_left - (int)ptr_1 -> x_pos ); frame_1.top = ( over_top - (int)ptr_1 -> y_pos ); frame_1.right = ( over_right - (int)ptr_1 -> x_pos ); frame_1.bottom = ( over_bottom - (int)ptr_1 -> y_pos ); frame_offset_1 = ( frame_1.top * sp_width_1 ) + frame_1.left; if ( ptr_1 -> animated == TRUE ) { frame_offset_1 += ( ptr_1 -> source_rect.top * sp_width_1 ) + ptr_1 -> source_rect.left; } // Calculate frame offsets for object 2 frame_2.left = ( over_left - (int)ptr_2 -> x_pos ); frame_2.top = ( over_top - (int)ptr_2 -> y_pos ); frame_2.right = ( over_right - (int)ptr_2 -> x_pos ); frame_2.bottom = ( over_bottom - (int)ptr_2 -> y_pos ); frame_offset_2 = ( frame_2.top * sp_width_2 ) + frame_2.left; if ( ptr_2 -> animated == TRUE ) { frame_offset_2 += ( ptr_2 -> source_rect.top * sp_width_2 ) + ptr_2 -> source_rect.left; } // The size of the overlapping rectangle over_width = abs( over_right - over_left ); over_height = abs( over_bottom - over_top ); // Loop through the bitmask checking for TRUE in // both of the objects bitmasks. for ( i = 0 ; i < over_height ; i ++ ) { y1_offset = ( i * sp_width_1 ) + frame_offset_1; y2_offset = ( i * sp_width_2 ) + frame_offset_2; P_p1 = &ptr_1 -> source_bitmask [ y1_offset ]; P_p2 = &ptr_2 -> source_bitmask [ y2_offset ]; for ( j = 0 ; j < over_width ; j++, P_p1++, P_p2++ ) { if ( ( *P_p1 == TRUE ) && ( *P_p2 == TRUE ) ) { ptr_1 -> pixel_hit = y1_offset + j; ptr_2 -> pixel_hit = y2_offset + j; return(1); } }// end for j }// end for i return(0);}// end Sprite_Sprite_Collide
Well that''s how I did it. I re-wrote John Amatos collision algos with bitmasks. If find the collision detection rather quick.
Guy
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement