Archived

This topic is now archived and is closed to further replies.

collision detection w/ ddraw surfaces..

This topic is 5672 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i''ve been reading/trying to figure out the collision detection tutorial by john amato (http://www.gamedev.net/reference/articles/article735.asp), and it sorta works, but i''m still having some problems... it does some detection, but it''s too broad... this is what i have (i copied most of it just to try to get it to work). i think it has to do with not using the surface correctly int CWaterPolo::CheckCollision ( CPlayer *Player, CPlayer *OtherPlayer ) { int left1, left2, over_left; int right1, right2, over_right; int top1, top2, over_top; int bottom1, bottom2, over_bottom; static int over_width, over_height; static int i, j; UCHAR *pixel1, *pixel2; left1 = Player->GetX(); left2 = OtherPlayer->GetX(); right1 = Player->GetX() + Player->CurrBitmap->GetWidth(); right2 = OtherPlayer->GetX() + OtherPlayer->CurrBitmap->GetWidth(); top1 = Player->GetY(); top2 = OtherPlayer->GetY(); bottom1 = Player->GetY() + Player->CurrBitmap->GetHeight(); bottom2 = OtherPlayer->GetY() + OtherPlayer->CurrBitmap->GetHeight(); if (bottom1 < top2) return 0; if (top1 > bottom2) return 0; if (right1 < left2) return 0; if (left1 > right2) return 0; 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; i = ((over_top - Player->GetY()) * Player->CurrBitmap->GetWidth()) + over_left; pixel1 = (UCHAR *)Player->CurrBitmap->GetSurface() + i; j = ((over_top - OtherPlayer->GetY()) * OtherPlayer->CurrBitmap->GetWidth()) + over_left; pixel2 = (UCHAR *)OtherPlayer->CurrBitmap->GetSurface() + j; over_width = over_right - over_left; over_height = over_bottom - over_top; sprintf(printBuffer, "Over_Width: %3d | Over_height: %3d", over_width, over_height); Console.AddMessage(printBuffer); sprintf(printBuffer, "pixel1: %d | pixel2: %d"); Console.AddMessage(printBuffer); for (i = 0; i < over_width; i++) { for (j = 0; j < over_height; j++) { if ((*pixel1 != _RGB16BIT565(255, 0, 255)) && (*pixel2 != _RGB16BIT565(255, 0, 255))) return 1; pixel1++; pixel2++; } pixel1 += (Player->CurrBitmap->GetWidth() - over_width); pixel2 += (Player->CurrBitmap->GetWidth() - over_width); } return 0; } any help would be appreciated

Share this post


Link to post
Share on other sites
I read the same article, and used those algos for my sprite engine. However, I made a bitmask for each sprite instead of locking/unlocking surface memory. That speeds things up quite a bit.

There was an error in the article, if I can remember what it was.

I was just looking over my collision algo. I could post it, but I don''t think you would get very much out of it. For starters there is the afore mentioned bitmask. It also works on both animated and non-animated sprites. It also returns the postion of the pixel in each sprite that is hit if I want to make a hole in the sprite.

Here''s the code anyway.


  
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

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;
}

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;
}

over_width = abs( over_right - over_left );
over_height = abs( over_bottom - over_top );

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



Maybe comparing the code, we can figure something out.

Guy

Share this post


Link to post
Share on other sites
A quick observation.
Shouldn''t

pixel2 += (Player->CurrBitmap->GetWidth() - over_width);

be

pixel2 += (OtherPlayer->CurrBitmap->GetWidth() - over_width);

Guy

Share this post


Link to post
Share on other sites