gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Hit test in C problems

#50956 - THI - Sun Aug 14, 2005 9:46 pm

Hi, i downloaded and installed devkitadv and a simple game( with source code), tank. I did a few conversions to make it a kind of side scroller.

Heres my compiled game http://gbadcdev.emuscene.com/FF/tank.gba.

Heres the problems

*Hit test is only working sometimes.
*Can get damaged when some bombs are in proximity,not actual hit

*sometimes bombs spawn in the middle of the screen
*sometimes bombs dont 'turn off' at x coordinate reaching 0

I feel that the last 2 problems are causing the first two...

Code:
// bomb movement and collision dectection and life removal
         for(loop = 0; loop < NUM_BOMBS; loop++)
         {
            // if off then random to turn it on
            if (bombs[loop] == 0)
            {
               rnum = RAND(10);
               if (rnum == 4)
               {
                  bombs[loop] = 1; // turn it on               
                  bomby[loop] = RAND((180-objbomb_HEIGHT)/2);
                  bombx[loop] = 240;
               }
            }
            
            // move the bombs
            if (bombs[loop] == 1)
            {
            // Changed to scroll bombs left
               bombx[loop] -= 1; // its on so move it
            
               // its on, so check for collision
               
               if (bombx[loop] == tankx)               
               {
                  if ( (  ( bombx[loop]+(objbomb_WIDTH/2))  > tankx) &&
                  (bombx[loop] < (tankx+objtank_WIDTH/2)))
                  {
                     // collision
                     life -= 2;
                     bombs[loop] = 0;
                  }
               }   
               if (bombx[loop] <= 10)
               bombs[loop] = 0;
            }
            
         } // end for bombs


thanks for any input, i have tried changing alot of things, every change i do to any factors seems to break the hit test.

#50962 - sajiimori - Sun Aug 14, 2005 10:23 pm

First of all, if you've got a boolean and two integers per bomb, then define a bomb struct like this:
Code:
struct Bomb
{
  bool alive;
  int x, y;
};

Bomb bombs[NUM_BOMBS];
Also, your random number test can look like this:
Code:
if(!RAND(10)) ...
And since you'd then just have two nested if statements, it could be flattened to this:
Code:
if(!bombs[loop].alive && !RAND(10)) ...
As for the bugs, you're establishing that the x coordinates of the bomb and the tank are equal, and then doing further tests on the x coordinate and doing nothing with the y.

The collision test can also be reduced to a single 'if', and it should really be a function like:
Code:
bool bombCollidesWithTank(Bomb*);

if(bombCollidesWithTank(&bombs[loop])) ...

#50971 - THI - Sun Aug 14, 2005 11:35 pm

ok, when i get the collision working, ill put it into a function..

but i try to simplify it like this...

Code:
if (bombs[loop] == 1)
            {
            // Changed to scroll bombs left
               bombx[loop] -= 1; // its on so move it
            
               // its on, so check for collision
               
               if (bombx[loop] == tankx)               
               {
               
               
                  if ((bombx[loop] == tankx) && (bomby[loop] == tanky))
                     {
                     // collision
                     life -= 2;
                     bombs[loop] = 0;
                  }
               }   
               if (bombx[loop] <= 10)
               bombs[loop] = 0;
            }


And the hit test does not register at all.

#50974 - sajiimori - Sun Aug 14, 2005 11:47 pm

Well, you're still checking the x twice, but there's no harm in that I suppose. Otherwise, keep in mind that the two objects have to have the exact same coordinates in order to collide. If your objects are not single pixels, they'll often pass through each other.

#50979 - THI - Mon Aug 15, 2005 12:14 am

yeah,i just left that second x check in their because without it it still produces the same result.

Code:
if (bombs[loop] == 1)
            {
            // Changed to scroll bombs left
               bombx[loop] -= 1; // its on so move it
            
               // its on, so check for collision
               if ((bombx[loop] == tankx) && (bomby[loop] == tanky))
                    {
                     // collision
                     life -= 2;
                     bombs[loop] = 0;
               }
            
               if (bombx[loop] <= 10)
               bombs[loop] = 0;
            }


would i just need to add some simple numbers to make it bounding box?
(like if (bombx = tankx +50) ?)

Height and width arent defined for the bomb, but are defined for the tank (objtank_WIDTH,objtank_HEIGHT)

#50983 - sajiimori - Mon Aug 15, 2005 12:49 am

No, adding values to the coordinates will just move them around, but they're still points. This is what you're looking for:
Code:
struct Rect
{
  int x, y, width, height;
};

// Implementation left as an exercise.
bool rectsCollide(Rect*, Rect*);
Give the bombs and the tank rectangles and check if they collide.