Skip to main content
gamedev.net
🔒 Locked

FPS movement

Started by Gumgo 2 replies 2.6k views
Original Post
Gumgo
Gumgo
I'm attempting to get a simple first person shooter player movement system working using the approach in this document. So far everything has gone smoothly - I have a function that takes a starting position, ellipse radii, and velocity, and uses collision detection and response to return a new position (the ellipse slides along walls as documented in the article). However, I'm a bit confused on how to go about implementing gravity and movement. What I want is for the player to be able to walk around and jump on relatively flat surfaces. If the surface is too slanted, the player should slide down. The article suggests to simply call the collision function twice - once for movement, then again for gravity. However, this doesn't seem like the best approach. How is this usually done in games? Any tips would be appreciated... I just need an idea of the overall approach to take.
Gumgo
Gumgo
Still need help with this.
Zenix
Zenix
I generally do two separate collision checks. One to let the player move from the scene, then a simple one to check if they're standing on the ground.
Gumgo
Gumgo
Thanks for the reply. Could you elaborate on that a bit more? It seems to me that the best way to do it, if possible, would be to only do one collision check with player movement and gravity all combined into one velocity vector, and compute the velocity for the next frame by taking the velocity from the last frame and adding gravity and player movement to it. Here are the issues I see with keeping the gravity separate (bad means gravity/z velocity separate, good means all velocity is 1 vector/1 collision check):

I attempted to do this, but one issue I'm having is computing the velocity for the next frame based on the velocity for the current frame. (For simplicity, this is without gravity adding to the velocity.) Obviously, if the player never comes in contact with anything, the velocity for the next frame should simply be the velocity for the previous frame. However, where I'm stuck is when the player does come in contact with a surface and slides.
The way sliding works is like this: the function collideWithMesh is called which moves the player to the point of collision based on a velocity parameter. At that point, a new velocity is calculated and collideWithMesh is called again with that velocity as the parameter... so collision is recursive. My problem is illustrated in the image below... the image shows two possibilities for the movement of the player over one frame: in both cases, the player starts above a surface, hits the surface, and slides down. In the first case, the player falls a lot and slides a little. In the second case, the player falls a little and slides a lot. However, in both cases, the next frame's velocity of the player should be the same, regardless of how much of the first frame was actually taken up by the player sliding or falling. So I can't just take the velocity from the last collideWithMesh call and use that (which would be the blue vector in the image. Yes, those are supposed to be vectors, I just didn't bother drawing arrows...).

My problem is that while the red vector represents what is actually the instantaneous velocity of the player at the starting position, the blue vector doesn't - it instead represents the distance left to move. I need some way of computing the new instantaneous velocity at the point where the player hits the surface (the top transparent looking circle).
How would I compute this vector?
(Does this make sense? Tell me if it doesn't and I'll try to make it more clear.)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.