Making a Platformer: Physics

I’ve decided I’d chronicle some of my experiences with my latest game. Specifically I thought it might be useful to work through the different aspects of creating a platformer. To start out I’ll run through the physics of a platformer and how to implement them using the grid data structure. So let’s get started!

The Foundation

As I’m sure you guessed we’ll use the grid data structure as the foundation for our physics. In this case I would suggest adopting a strict grid. If you plan on have a scrolling platformer then I would also suggest a second modification. Instead of simply creating a 2-d array of cells create a hash of cells. This will allow you to have an arbitrary number of cells in either direction (+/- infinity). You can do so like this:

// arbitrary large number
// should be greater than the real width of your grid
private static final int MAX_WIDTH = 50; 
private Cell getCell(int x, in y) {
    Cell c = cells.get(x + y * MAX_WIDTH);
    if (c == null) {
        c = new Cell(x, y);
        cells.put(x + y * MAX_WIDTH, c);
    }
    return c;
}

With that out of the way I would also create two helper classes. A collision handler which is called whenever two bodies intersect, and an object which knows how to move two bodies out of intersection. I call them Response and Resolver respectively. In my experience the Response contains a big switch which figures out whether to resolve two bodies or not, and the Resolver simply takes one moving body and moves it such that it no longer intersects with a second body — we’ll take a look at that in detail below.

The Fall and the Jump

To facilitate intersection testing and response described above and in order to apply gravity to bodies in the game let’s define a new interface. For this exercise let’s go with the following:

interface GravityEntity {
    public static final float GRAVITY = 9;
    public static final float MAX_SPEED = 20;
    public void setGrounded(boolean grounded);
    public boolean isOnGround();
    public float getX();
    public float getY();
    public float getWidth();
    public float getHeight();
    public float getXVelocity();
    public float getYVelocity();
    public void setPosition(float x, float y):
    public void setVelocity(float x, float y);
    public void update(int delta);
}

So all of our game objects will be gravity entities. In order to simulate gravity we need to implement update like follows:

public void update(int delta) {
    if (!isGrounded()) {
        yVelocity += GRAVITY;
        if (yVelocity > MAX_VELOCITY) {
            yVelocity = MAX_VELOCITY;
        }
    }

Nothing too special, our objects accelerate downwards when they’re falling. In order to complete things we need to update our game loop, too. The basic logic is as follows:

  1. Set each object as falling
  2. Test for collisions
  3. When a body collides against a second’s top then the first body is grounded
  4. Update each body

Now that we have gravity implemented it’s simply to add a satisfying jump. All we need to do is set the y velocity for an object appropriately. In my demo I set it to roughly -20 when you’re running.

Handling Intersection

At this point we’ve got a system to detect intersections and basic gravity implemented. Still we need a way to check the condition outlined in step 3 above. How can we determine whether an object is standing on the ground or running into a wall? The Resolver answers this question for AABB objects. An object A is standing on B when:

  • A is moving down, i.e. has y velocity greater than zero
  • Before A moved it was above B, i.e. A’s bottom – A’s y velocity less than B’ top

Likewise you perform the same check for each side on A. Once you’ve determined on which side the collision occurred it’s easy to back the first object out of intersection with the second. For example if the collision is between A’s bottom and B’s top I will move A up such that the two no longer intersect and set A’s y velocity to zero.

For a full implementation of this in actionscript see my Resolver.as. Remember to set A as grounded if it collides with B’s top!

Conclusion

Alright that wraps up the physics behind a simple platformer. With this system in place you have everything you need to create a demo similar to this one. Next time I’ll look at some of the other elements in a platformer including scrolling with a camera and scripting. As always I hope you found this useful and let me know if you have any questions or comments.

Related Posts

5 Comments

  1. tw
    Posted April 11, 2009 at 12:58 pm | Permalink

    grid data structures to the rescue once again! As usual this is a nice overview to get people started. Thanks for sharing!

  2. Gornova
    Posted April 14, 2009 at 1:53 am | Permalink

    all i need is this :D in particular collision detection on a platform for player vs floor and player vs wall is not obviuous!

    maybe you can share a full-code demo ?

  3. Posted April 14, 2009 at 6:55 am | Permalink

    Hey Gornova if you check out this file linked above you’ll see how I determine whether the player is “standing” on top of something. Just imagine that the player is the primary TangibleEntity and the floor is the secondary TangibleEntity.

  4. Gornova
    Posted April 14, 2009 at 10:20 pm | Permalink

    the problem is not his, but combinations of movements like: right + jump and left + jump :(

  5. Posted April 15, 2009 at 11:09 am | Permalink

    Nice article! What a great conceptual platform to create a platformer!

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>