collision-detectiongravity

Collisions between game objects and the floor with regards to gravity?


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.


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: