Question

How do games with gravity handle the relationship between moving things like players, monsters, or objects and the floor? Is the player constantly "falling into" the floor and being bounced back up?

Two ways to react to collisions that I have found are moving the player back to his previous location before the collision, and testing the new position before moving to see if it would result in a collision, but I don't see how either of these could deal with a platform that is rising upwards and needs to be able to lift the player. I'm looking at this from a 2D game design perspective, but I imagine that the same problem occurs in 3D game design. Any hints? Any references that I should check out? Thanks.

Was it helpful?

Solution

You might want to check out GameDev.net's Gravity FAQs for some basic info.

Since you are making a game and not a highly accurate physics modeler than we can get away with doing Euler integrations. If your need for accuracy increases the most popular integration method that I see used is a Runge-Kutta (RK4) integration. You most likely won't need these for a simple game but they definitely are used in more advanced physics simulation and 3d games. The disadvantage with using RK4 is slightly increased complexity and slightly slower. It is very accurate though, but for now, lets stick with good ole Euler.

I asked a similar question, "How do I apply gravity to my bouncing ball game", and got several good answers. The first thing you'll do is choose an arbitrary gravity constant for your game. In my bouncing ball application I use a default gravity constant of 2000px/s. You'll want to play with this gravity constant to get the desired effect for your particular game.

Next, you want to make sure that you are rendering your game and updating your game objects independently. This is to prevent your in-game objects from moving really fast on fast computers and slow on slow computers. You want the physics and speed with which your objects move around to be independent of the computer speed. A good article on this is Game Physics: Fix your timestep!.

So how do we do that? You keep track of how much time has passed since the last call to your Update method. I created 2 threads, although it isn't directly necessary. I have a game update thread and a rendering thread. The update thread controls updating the in game objects positions. The update thread knows when it was previous called, the current time and from that calculates the elapsed time since the update method was called.

To apply gravity we will simply add to the Y velocity of our object by our gravity constant multiplied by the elapsed time.

private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;

public void updateGame()
{
    currentTime = System.currentTimeMillis();
    float elapsedSeconds = (currentTime - previousTime) / 1000f; 

    foreach(GameObject gameObject in gameObjects)
    {
        // Apply gravity to velocity vector
        gameObject.velocity.y += (gravityConstant * elapsedSeconds); 

        // Move objects x/y position based off it's velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

That will move all your objects based on their velocity vector's and apply gravity to them based on your gravity constant. Best of all it does it independently of the computers speed!

To answer your other question, yes the objects will constantly have the "force" of gravity on their y vector. So it will be constantly colliding with the floor. However, one thing you want to do is use an Epsilon value to eventually bring your gameObject's velocity to zero. Then, during collision detection as part of your pruning process you can usually skip checking if a non-moving object is colliding with anything (not vice-versa though!).

What I like to do with collisions is once I find objects colliding (penetrating each other), I'll push them apart by their minimum translation distance (MTD) which seperates them. This step is key otherwise you will get the frequently seen bug in games of objects "stuck" together jitterly moving about. Once they are separated I calculate my collision response.

Using this method it will work fine in your described scenario of a rising platform. The platform will continue to rise, the gameObject will separate itself using the MTD between itself and the platform and it will naturally rise with it.

If you need help on the collision response I would suggest looking at:

OTHER TIPS

One approach used in some games is to cheat: have a separate state for walking vs in the air. While walking, the game engine can determine the slope of the surface being walked over and, if not too steep, move the character in the direction of the surface as well as giving the character the proper vertical placement relative to the surface.

As for physics, I'm becoming a fan of verlet integration as described in Gamasutra: Advanced Character Physics. It simplifies physics update equations (don't have to keep track of velocity!) and it simplifies collisions (don't have to adjust velocity!). That said, it does have a few nuances if you need accuracy.

One of the most complete textbooks on this subject is Realtime Collision Detection by Christer Ericson. He has a companion blog too. Eric Lengyel's Mathematics for 3D Game Programming and Computer Graphics is useful too.

I'm not specifically a games programmer, but this is my understanding:

  • in an ideal world with an "infinite frame rate", you'd detect the collision at precisely the moment it occurred, and use a bit of standard physics to model the new velocities and accelerations of the bodies following the collision (see a standard high school mechanics textbook, or various books entitled things like "Physics for Games Programmers")
  • in reality, because you have a fixed frame rate and hence bodies only move with a certain granularity, you usually need to add an extra trick, such as calculating in advance the relative path that bodies will travel on the next frame and seeing if any of the paths intersect
  • if they do intersect, then the point of intersection will actually be an estimate, but slightly inaccurate, of the point at which the bodies really would have collided; you then have the choice of not caring and taking that estimate as the point of intersection and linearly interpolating to get the velocities at the point of collision, or doing a more precise calculation now you've found out that they will intersect, to get the actual point/time/velocities of collision

In addition to modeling collisions, a good approach is to also model continuing transfers of energy (or momentum, or just velocity, depending on the complexity of your simulation). When your player is standing on a platform, store that information in the object representing the platform, and any time the velocity of the object is adjusted you can directly apply that change to the thusly linked player or other objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top