Sign in to follow this  
AstroNox

Jumping Physics

Recommended Posts

Hello everyone. I'm new here, so I'm not sure if such a question has been asked before; but I'll ask anyway: Does anyone know how to add a jump function to a 3D game, using a physics engine? Currently, I'm doing a FPS game in OpenGL together with Tokamak, and this question has plagued my mind... The reason being that I do not know how to find out whether my character is standing on something before allowing a jump. Of course, if the floor is fixed, this is easily done with a simple less-than/greater-than operator. However, the game allows standing on platforms, and these platforms may move--in all directions, even up and down. How do I find out if I'm standing on something before I allow a jump? The game does not allow a double jump, so that can be put aside. Hope someone can help because I need to find this out asap for my presentation... which is in fact tomorrow... =/

Share this post


Link to post
Share on other sites
well, your question is quite fuzzy for me, but i'll try some gueses. So you have an actor, and you want to apply a jump function. Then there is a physics engine, and you want to check if that actor is sitting on something. So first a question: how do you represent your entities? How do you check collision, if there is a physics engine? is there any scene graph present? Please be more specific about your implementation.

Share this post


Link to post
Share on other sites
1. My entities are represented as simple rigid body AABBs (each actor is one AABB).

2. In Tokamak there is a collision callback feature that triggers when two objects collide (actually you can define different collision IDs to different rigid bodies to define whether to call the callback function on collision). The collision callback is not called however, if either of the two collided bodies are not moving relative to one another.

3. Scenegraph, no. It's a simple game map, just an open space with some blocks to jump on. Thats all (it's more of a simulation at this stage). Basically, I can land on any other actor, be it a player pawn or a block.

The question I'm having here is how do I determine if I'm standing on something (or sitting on, whatever). Collision detection alone is not enough because I might collide side to side, not top-down.

Share this post


Link to post
Share on other sites
The way I do it is in the collision response code, check every point that the player touches that the player can jump from, and if that point is where their feet are, allow the player to jump (after all, they are on the ground). Also, during every simulation loop, make sure you disable the player's ability to jump, or you'll be able to jump in mid-air. Then, if the player wants to jump, and they're on the ground, give them an upwards velocity of some reasonable value (add an upwards force or something similar), and that'll make them jump. You can also use this jumping method to allow movement only when the player's on the ground.

Share this post


Link to post
Share on other sites
The jumping part should be easy - just apply an impulse in the upward direction and let gravity take it from there. As for figuring out when you should be allowed to jump, there are probably 'real' solutions, but you may have to settle for a 'my presentation is tomorrow' solution. A real solution might be to query Tokamak to see if your object is in resting contact with something, but I don't know enough about Tokamak to know if this is an option. A hack solution would be to disallow jumping when the vertical component of your velocity is small. One pitfall here is that the condition will be met at the apex of the jump as well as when you're on the ground. I can think of some ways you might work around this though. Also, depending on when you query the velocity, it may always have a non-zero vertical component due to gravity even when you're resting on an object. So you'd have to set your threshold accordingly.

Hm, I guess those weren't very good ideas after all. I'll go ahead and post this though, and maybe others will have better suggestions.

[Edit: The above posts sort of render mine irrelevant. It seems the real problem is determining if the bottom of your AABB is in contact or has collided with something, which may be difficult if you don't have access to that info yourself. If your world is simple, perhaps you could throw together a little of your own AABB collision code if necessary...]

Share this post


Link to post
Share on other sites
Thanks for your reply. I thought of this as well, the apex thing. Perhaps this is a good last minute resort which I could settle just for tomorrow, but does anyone know of a good solution this problem?

Share this post


Link to post
Share on other sites
For jumping in my game I have the following:

#ifdef MULTIPLE_JUMPS
if( ySpeed < 300.0f && ySpeed > -100.0f && player_jumps<MULTIPLE_JUMPS){
player_jumps++;
#else
if( player_is_on_ground() ){
#endif
ySpeed = keys[ controls.crouch ] ? PLAYER_JUMP_SPEED*1.25f : PLAYER_JUMP_SPEED;
ySpeed *= timedamage_has(TIMEDAMAGE_DRUG) ? 1.3f : 1.0f;
}



player_is_on_ground() returns true if there is a collision detected if player moves down a little bit.

Don't know if tokamak could do this though...

Share this post


Link to post
Share on other sites
i don't know anything about Tokamak, but if it detects a collision, how do you handle the collision response? I mean let's say you collide with a wall in front of you. now isn't there some collision response, such a force vector that pushes you back a little. cause if there is some info, you could use it to know from what direction was the collision. If this collision is from below you, then you can set a flag to true (you are resting on the ground). when you jump, set the flag to false (you are in air). you can jump only if the flag is true.

[edit] sorry, i think i've posted at the same time sirGustav did. The idea is quite the same, but the moving down is not too good, because you can move down and forward in the same time, and you can colide first with a wall, and then with the floor. if there is just moving down, it might really work.

[Edited by - meeshoo on September 8, 2005 8:02:47 AM]

Share this post


Link to post
Share on other sites
meeshoo, I think you misunderstood me, I don't ever move the player when testing for jumping...

The engine I am using(Genesis3d) allows you to do check if there is a AABB collision with the world(or anything else for that matter) from point A to point B.
So the player_is_on_ground() looks something like this(I can post the source, but I doubt that it would be any usefull):

#define MINIMUM_MOVEMENT 0.001f
int player_is_on_ground() {
Position newPosition = playerPosition;
newPosition.Y -= MINIMUM_MOVEMENT;
if( collisionWithWorld(playerPosition, newPosition) ) return 1;
else return 0;
}



and doesn't modify the position, or doesn't care abot the players movement(only his/her current position). This code have been in use for atleast 1.5 years (along with the rest of the movement code) and I haven't discovered any bugs with it :)

BTW, your idea suffers from "mid air jumping":
If the character is standing on a platform and starts to walk out from it. In mid-air (while falling) he can jump, since the onGround variable is still true.
To avoid this you have to (AFAIK) check if there is something under the character all the time(or when he/she jumps).

Share this post


Link to post
Share on other sites
Well, thanks for the replies everyone. Yes, there are many issues regarding this jumping problem, and it's not so easy to tie up all ends either.

SirGustav: Regarding your solution, that might just work--thanks for the insight. The only concern I have is the possible exploitation of "quick-landing" with such a method.

Share this post


Link to post
Share on other sites
I have no knowledge of Tokamak, but I'll try to help..

Check for collision of a small, invisible block slightly protruding the actor's feet, and slightly smaller than to reach the sides, so it is essentially only checking if the feet are on the ground.


____________
| |
| actor |
|___ ____ ___|
|____|
block ^


That seems to be a solution independant of any sort of physics engine, it's just simple intersection checking. Or am I missing something?

Share this post


Link to post
Share on other sites
No need to apologize. This forum is about helping other people and learning, and I hope I helped someone ;)

Quote:
The only concern I have is the possible exploitation of "quick-landing" with such a method.
What do you mean with "quick-landing"? I believe that most games allow you to jump the second you land. To simulate real-world jumping (ie that you can't jump the second you land) you can something like this:

const float LIMMIT = 0.2f; // adjust this value so that it fits w/ gameplay
float jumpPower = LIMMIT * 2.0f; // make sure it is larger than the limmit
while(true) {
if( player_is_on_ground() && jumpPower < LIMMIT)
jumpPower += TIME;
else
jumpPower = 0.0f;
/* other gameloop stuff */
if( player_is_on_ground() && jumpPower > LIMMIT )
do_jump();
}

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

In a physics engine, to make an actor "jump" is as easy as to apply a vertical force, opposed and greater than the force of gravity * weight of the actor, for about a second or two.... this will make the actor accelerate upwards... and the force of gravity applyied in the system will make the actor fall again a few seconds later.

But, in order to work, you must move your actor by applying forces to it, and not by changing its velocity or position directly (something that's very common in quake like games)

-VicViper

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this