Need help with game physics and collisions in 2d.

Started by
1 comment, last by cybercoward 16 years, 8 months ago
I am very new to game programming only been experimenting off and on for a few months now. I am trying to make a game similar in engine to Megaman X. My problem is that I want to use acceleration to give different velocities instead of having a constant velocity while jumping. I have a problem described in the Gravity Faq in the resources of the site and am wondering if I will have to use some kind of line intersection or something. Right now I am using 2 collision tests bounding box style to detect if x or y velocity added to position will collide with a tile. I am using a system right now that will check to see if the surrounding 1 or 2 tiles are colliding in the box with a formula that checks to see if distance from box centers are less than distance of half box 1 height plus half box 2 height. This is basically it: test1 = (h1+h2)^2 test2 = (d1-d2)^2 if test1>test2 then collision = 1 where h1 and h2 are half width/height of box 1 or 2 and d1 and d2 are the distances from the center points of the boxes. I squared both sides of the test to make sure that d1-d2 wouldn't come out negative as I only need its magnitude. I do 2 tests one for y where I sent player y position + player y velocity as function arguments and one for the x, but the problem I get is only with y velocity. As I said it is described in the Gravity Faq. Right now I hit jump and he jumps until hitting the ceiling then falls and keeps falling through the floor to my lower limit of tile map. I am thinking maybe I can extend the value of the y test to include tiles that are player position + velocity distance away instead of just next 1 or 2 tiles to try and fix the problem. I think this will work but I was just wondering if anyone else has had the problem while learning game programming and if anyone had a better solution. I also have a few doubts about it working because maybe if I had a floor only one tile thick and my velocity was too high it would pass through the floor. Maybe a line intersection algorithm or something would work but as I am doing 2 seperate tests I only need it in 1 dimension and I don't know alot about line intersection code. Any tips welcome.
Advertisement
You're not using bounding boxes. You're using circles. Because checking the distance between two centers is essentially a cirlce-circle test.

What you've probably forgotten is to set the player back afte a collision has occurred, though that's not clear from the info you gave.

Anyway, an AABB-AABB (axis-aligned bounding box) test would go as following, in pseudo-code:

Box { x, y, width, height } // The center here is (x + width / 2, y + height / 2)!bool Collide(Box A, Box B){	if(A.x + A.width < B.x) // If A is totally to the left of B		return false;	else if(A.x > B.x + B.width) // If A is totally to the right of B		return false;	else if(A.y + A.height < B.y) // If A is totally below B		return false;	else if(A.y > B.y + B.height) // If A is totally above B		return false;	// Otherwise, they collided	return true;}


The next step would be to push the moving box out of the stationary one, when a collision occurs. The most basic approach would be to check how deep it intersects with the other box, for all 4 sides, and move it out in the direction that it intersects least. Or you could check from which direction the moving box came, and see how far it intersects in that direction, then push it back by that distance.
This ensures that the moving box ends up just before the other box, instead of getting stuck inside it, or hovering above it.

I hope that helps you somewhat? :)
Create-ivity - a game development blog Mouseover for more information.
Thanks man, after I added velocity limit of half a tile and used your idea it works
with an added collision test but still runs very fast on my 200MHz machine, which
is good. I only have 3 collision checks right now because I haven't put anything
but tilemap and a player object in so I'll probably have to optimize my code alot
later but that is another story.

I am using bounding box collision but it is more like the standard circle-circle
test than the usual corner by corner box test. That is why I didn't have the
pythagorean equation in my formula I posted though, because it doesn't really
need that part for that kind of check, here is the long version to clarify what
I am doing:

box1.hx - first box half width
box1.hy - first box half height
box1.x - first box x center position
box1.y - first box y center position
box2.hx - second box half width
box2.hy - second box half height
box2.x - second box x center position
box2.y - second box y center position

Now I know the formula I am using looks alot like the circle-circle test but it
isn't this is it in a nutshell, I got it off some site either gamedev.net or
allegro.cc can't remember which.

box1.y-box2.y=distance y
box1.x-box2.x=distance x
box1.hx+box2.hx=minimum allowed x distance between box1 and box2
box1.hy+box2.hy=minimum allowed y distance between box1 and box2

Now the formula is to check to see if distancey is less than minimumy and
distancex is less than minimumx at the same time and if so it will return 1
for collision. The original formula was something like this in C:
if (abs(distancey)<minimumy && abs(distancex)<minimumx) return 1;
But I don't using alot of math functions in C other than the operators that
aren't in libraries and wasn't sure if you had to include math.h to get the abs()
function so instead I squared both sides to get rid of the possible negative and
that is the part that makes it look like circle-circle test. So now it looks
like this in C:

if (distancey*distancey<minimumy*minimumy
&& distancex*distancex<minimumy*minimumy)return 1;

Of course I use much shorter variable names in my real program but you get the
idea by now I'm sure. Like I said though after some tweaking of my code your
idea works great thanks for the help. Sorry I didn't clarify better on my
box-box code in original posting but I was in a hurry before heh.

This topic is closed to new replies.

Advertisement