Advertisement

Game Physics !!

Started by March 01, 2000 12:31 PM
12 comments, last by tcs 24 years, 7 months ago
Hi ! I have a problem with my game physics. My engines displays a large landscape, and my player walks on it. When I walk a hill down, my player is mid-air for a short period of time and falls very quickly back to the ground. This happens a few hundred times. Beacause of this I can''t jump while walking down a hill (you can''t jump while you are in the air). The view also jumps up and down very quickly, so it doesn''t look good. I tried to set a minimum height to avoid this "sliding down a hill" thing, but this won''t work. It depends on the current FPS, cause a longer time between the snapshots mean that the player could gain a higher height. Even if you scale the minimum height relative to the elapsed time it won''t work beacause of the nature of the terrain. Raising the gravity is also no working solution. Any ideas ? Tim
Tim--------------------------glvelocity.gamedev.netwww.gamedev.net/hosted/glvelocity
When you move your character you're adding a horizontal vector to its position. Am I right in assuming this? If you do it like that there is no solution to your player 'flying' down the hills. It is actually the same effect as if the character was jumping on flat ground.

What you need to do is to check the slope of the ground that the character is on then have the character move tangentially to that slope. (Which is what we do in real life when running down a hill.)

This can be done by parallel projecting the move vector on to the ground plane, where the projection is along the ground normal.

 \P---> v    \\     _   \\    / n   \\  / a   \/       \             \ g 


P = character
g = ground plane
n = ground normal
v = move vector
a = parallel projected move vector

The parallel projection is done with:

a = v - dot(v,n)*n





Edited by - Spellbound on 3/1/00 1:08:08 PM
Advertisement
A simpler approach might be to set a flag whenever the player is resting on the ground. Then, whenever they take a step forward check the flag. If it''s true, just keep them at the elevation of the new terrain they are standing on. Also, you could set a cutoff to account for cliffs. In other words, if the elevation difference between where they were and where they are is greater then a certain amount, don''t "jump" them all the way down to ground level again, let them fall.
If a man is talking in the forest, and there is no woman there to hear him, is he still wrong?
Are you sure your physic engine is requested before/after each frame ?
If it has a relation with frame rates, it might be because your physic logic cannot be executed due of the lack of time.

You must also check the player against the ground, that is you must be sure that the player is walking and not in the air, a simple collision detection/map trick could be enough.

Normaly you''re always affected by gravity, so you might choose to add a vertical downside vector to represent it.

Those are only thought, cause I''ve not think about that problem for now, people are flying in my little 3d engine :o)

-* Sounds, music and story makes the difference between good and great games *-
-* So many things to do, so little time to spend. *-
Ingenu - I do it that way. Before each frame cNotion.Apply() is called. But I pass the time of ms elapsed since the last call to it, so the function know how much should happen. I have a downvector, but gravity isn''t enough. The problem: When I''m walking down high hill, you accelerate over the edge and fall down. Like in reality. But when you walk down a low gradient, the problem appear: You leave the ground because of your horizontal acceleration, and get dragged back to it because of the gravity. This happens a few hundred times, so your view shakes around and you can''t jump couse half the time you are in the air. I have added a minimum height: When the player has not enough enough "up" acceleration, and its height is under this minimum, he will be Set to the ground. This works good when the Apply() function is called very often, say 45 times a second. But when your FPS gets lower, it doesn''t work. My physics work perfect FPS independent, but this doens''t work with my timescaling cause when a higher time is elapses, you are higher above the ground and your minimum height is exceeded. Scaling the minimum hight relative to the elapsed time also doesn''t work.

Tim
Tim--------------------------glvelocity.gamedev.netwww.gamedev.net/hosted/glvelocity
Spellbound - If I understand you right you showed me how to let my
player stay on the terrain. This is not my problem. I use heightmap
and interpolate between the four nearest height values. This way I could
always get the height for the position of my camera.

Novalis - In fact I have a flag to indicate wheter my player is in the air
or not. The problem is that my physics are called before each frame. So I have
to take the elapsed time into account. The problem is that when you walk over an
edge you have a height difference between your player and the ground. When a
higher amount of time went past my player moves more over the edge, so the
height increases. So the the "when my player exceeds a given height set him
not back to the current terrain height and let him descent down by gravity"
approach doesn''t work. I can''t scale this minimum height realtive to the
elapsed time, cause the terrain under my player can be of any shape and so it is
not predictable how much the height increases with time.

I hope my English was good enough to make myself clear.

Tim
Tim--------------------------glvelocity.gamedev.netwww.gamedev.net/hosted/glvelocity
Advertisement
Well, what about this. Suppose you call your physics function with a max amount of time of (as an example) one second. If the elapsed time was greater then one second, you just call it several times. It''s a bit of a hack, but if you want more realistic results, I guess you''ll need to do more calculations...
If a man is talking in the forest, and there is no woman there to hear him, is he still wrong?
A better approach (in my judgement) is to create a multimedia timer callback function and set it to update about 50 to 100 times a second. Within this function, update your sprites'' horizontal and gravity velocities, then calculate the new position of the sprite.
At each mmtimer call, create a line array from your sprites'' previous position to the newly calculated position, then test each pixel in the line array for collision with the level construction.

I have done this in my game and it works sensational, no matter what FPS the game is blitting, all my sprites are timed perfect, and the collision detection is flawless!

Ive attempted to do it by the frame updating, but this requires a whole lot of calculation which I think would just complicate things and cause collision problems etc..

Your choice.


  Downloads:  ZeroOne Realm

Sorry guys, but everyone seems to be far away from my problem. I don''t call my routine twice or with a maximum amount of time (have I ever said this ? Why the heck does anybody assume this ?). My calculations are RIGHT, and WORK, regardless of the elapsed time. And I don''t have any problem with collision detection. my collision detection works PERFECT. My problem is another. I wan''t that the player runs hills down smoothly. He shouldn''t slide down the hills. wtf has this todo with collision detection ? I think I have explained my problem properly.
Tim--------------------------glvelocity.gamedev.netwww.gamedev.net/hosted/glvelocity
Maybe I need more information, but according to what I have heard, I think this sort of thing might fix it...

It''s a matter of when things are updated. If you get the input, update the player position, then inflict physics upon the player to get his new position, and THEN draw the screen, things should come out right. As long as the drop is slight enough and the FPS isn''t too low, this shouldn''t be a problem.
- Hai, watashi no chichi no kuruma ga oishikatta desu!...or, in other words, "Yes, my dad's car was delicious!"

This topic is closed to new replies.

Advertisement