# Collision Detection Problem

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

## Recommended Posts

Hello everybody! I'm kind of going crazy over an absurd problem of collision detection. Basically, the system ( which is HGE ) reports a collision when my player box is standing on the floor ( player_box.low_y = floor.high_y ). This not only does not make any sense, but the same result does not happen when I hardcode two boxes one standing over the other, so I don't really know what to think.. This is my code:
void Fighter::think () {
// H COLLISIONS HANDLING
hgeRect fTry = fSpace;				// Copies Fighter bounding box
// hSpeed > 0 :     RIGHT
// hSpeed = 0 :     NOT MOVING
// hSpeed < 0 :     LEFT
float hSpeed = fSoul.getDx();		// Gets Fighter horizontal speed

if ( hSpeed != 0 ) {				// If there is a possible collision to manage..

// Projects Self into the Future
if ( hSpeed > 0 )				// Expands the bounding box in the moving direction
fTry.x2 += hSpeed;
else
fTry.x1 += hSpeed;

// if cannot go there ( foreach square TODO )
if ( fTry.Intersect( &rightWall ) ) {
// Limits hSpeed
if ( hSpeed > 0 )
fSoul.setDx( rightWall.x1 - fSpace.x2 );	// Limits speed to space between Fighter and the wall
else
fSoul.setDx( rightWall.x2 - fSpace.x1 );
}

}

// V COLLISIONS HANDLING
fTry = fSpace;						// Resets try bounding box
// vSpeed > 0 :     FALLING
// vSpeed = 0 :     NOT MOVING
// vSpeed < 0 :     RAISING
float vSpeed = fSoul.getDy();		// Gets Fighter vertical speed

if ( vSpeed != 0 ) {				// If there is a possible collision to manage..
// NOTE: Due to gravity, vSpeed is usually never 0; at least 0.3
// Projects Self into the Future
if ( vSpeed > 0 )
fTry.y2 += vSpeed;
else
fTry.y1 += vSpeed;

// Cannot go there ( foreach square TODO )
if ( fTry.Intersect( &floor ) ) {
// FLOW ENTERS HERE EVEN THOUGH IT SHOULDN'T
// Limits hSpeed
if ( vSpeed > 0 ) {
fSoul.setDy( floor.y1 - fSpace.y2 );
// Resets Available Jumps
fJumps = N_JUMPS;
}
else ; // AND ENDS UP HERE
// commented this because otherwise my sprite vanishes =P
// fSoul.setDy( floor.y2 - fSpace.y1 );
}
}
}


The handling for the horizontal and vertical part are exactly the same, but the problem rises when I try to jump after I'm landed on the floor. Then the game detects an intersection between my sprite and the floor, even though that is impossible ( I've debugged tracking all the variables.. ). It seems all right to me =( If you need additional information just let me know! Thanks in advance for any advices!

##### Share on other sites
One thing that comes to mind is floating point precision errors. If you have two floating point numbers (I assume that player_box.low_y and floor.high_y is floating point and not integers), you can't guarantee that the check (player_box.low_y == floor.high_y) returns true even if they seems to be equal. In the same way, you can't guarantee that player_box.low_y - floor.high_y returns 0, even if they are equal.

I had an error like that yesterday as well, and it took a while to find the problem (collisions were missed randomly, or so it seemed). I noticed that when my collision box' lower y value and the ground surface's y value were equal, the distance wasn't 0, it was something like 1e-15, or sometimes -1e-15 (or some other very small number).

So what you can try is what I did, do a "if (abs(player_box.low_y - floor.high_y) < 1e-12) distance = 0; else distance = player_box.low_y - floor.high_y;" on your distance calculations, and other floating point operations which may be sensitive to precision errors.

Hope this helps.

Edit: My numbers are based on double precision floats. Since you're using single precision floats, you might need a higher threshold.

##### Share on other sites
Also, if your sprite is subject to gravity, it might go like this: Sprite lands. Sprite is dragged down Y distance by gravity. Sprite is checked for a collision, which now exists. Sprite is moved up Y distance to resolve the collision.

From the computer's viewpoint, the sprite is always colliding. But, because the collision is fixed before the player can see it...

Edit: Nevermind, you check for that. Provided that check works, it shouldn't happen.

##### Share on other sites

I've checked my code and these are the results:

- if I put a
if ( player_box.low_y != floor.high_y )    check_collision_code();
it works. ( but I cannot use this solution as it introduces a new couple of bugs, and it's also bad code which I really cannot stand )

- if I put a
if ( abs( player_box.low_y - floor.high_y ) < 1e-12 )     player_box.low_y = floor.high_y;
before the check collision code it still doesn't work, even though it actually enters the if.

1) I've debugged my code, and usually the variable watches signal when there is a problem with floats ( for example, my gravity offset is reported as 0.29999999998 ), but the Ys of the two boxes do not have any floating part.

2) If I set the floor bounding box a little more higher, let's say above 600, my code works. If I move the floor lower, at 700, the bug reappears. This could be related to non-integer movement; though to me it seems unlikely, because the limit that trigger the bug is precise ( 639 ).

Also, is there a way to automatically round floats to max 2 decimal digits? If I could do that I could avoid in block all this kind of problems..

##### Share on other sites
My first instinct there would be to check collision to make sure I'm checking against either all relative or all absolute positions and not, say, relative and absolute positions, somewhere.

##### Share on other sites
I'm sure I'm doing the check with the absolute position of every box, mostly because I never use a relative position for anything =P

##### Share on other sites
...I got nothing. Try stepping through your code, if you can?

##### Share on other sites
You mean debugging step by step?

##### Share on other sites
Could you post your intersect function and tell what x1,x2 and y1,y2 stand for?

##### Share on other sites
x1, y1 stand for the coordinates of the top-left vertex of the box.
x2, y2 stand for the coordinates of the bottom-right vertex of the box.

The intersection function is not mine, it's the one written in the HGE engine, so I think it's correct.

I've found the bug though.
It's here, when I expand the fighter's box:

if ( vSpeed > 0 )     fTry.y2 += vSpeed;else     fTry.y1 += vSpeed; // This triggers the bug with the intersection

Now I've found it.. but still this line shouldn't trigger a collision downwards!

Ideas?

1. 1
Rutin
38
2. 2
3. 3
4. 4
5. 5

• 12
• 15
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633354
• Total Posts
3011493
• ### Who's Online (See full list)

There are no registered users currently online

×