I'm currently working on a platformer and thought I'd write about some of the lessons learned along the way. I just finished writing my first post which focuses on writing the
physics for a platformer. Here's an early demo of my engine in action:
*Click to play*
In order to accomplish this I needed to implement three things. First, some form of collision detection. In this case I use AABB's and the
grid data structure (originally borrowed from the N tutorials.) This approach divides the game up into a set of cells and then checks the bodies in a given cell against eachother for intersection. With this in place we're able to determine when two bodies intersect.
With boolean hit detection in place we next need to implement an interface which the grid can use. I generally use something like so:
interface PhysicalActor {
public float getX(); // top left corner
public float getY();
public float getWidth();
public float getHeight();
public float getXVelocity();
public float getYVelocity();
public void setPosition(float x, float y); // sets top left corner
public void setVelocity(float x, float y);
public void onCollision(PhysicalActor body, int side); // put custom response logic here
}
Since most platformers involve running and jumping we'll need some way to represent gravity. The easiest way is to simply increase the speed of an object downwards a given amount on each update of the game loop. You'll probably want an additional interface to represent this:
interface GravityActor {
public boolean isGrounded(); // is on the ground
public void setGrounded(boolean b);
public void applyGravity(); // should be called on update whenever not grounded
}
In practice I take the following approach:
1. Set each object as not being grounded
2. Sweep for intersections
3. Resolve any intersections as necessary
4. Mark objects as being grounded as necessary
5. Update each object, accelerating those which are falling
In order to address step #3 and #4 we need to develop a way to resolve collisions and determine on which side a collision occurs. I use a simple approach, imagine you have two AABB's object A and object B, if
* A is moving down, i.e. has y velocity greater than zero, AND
* Before A moved it was above B, i.e. A’s bottom - A’s y velocity less than B’ top
* THEN A struck B's top side, therefore A should be grounded.
You can easily adapt this approach to determine whether A struck B's bottom, left, and right sides.
Anyway, that about covers this whirlwind tour :-) Feel free to check out
my original post for additional details, links, and code. You'll also find source code for the grid data structure I touched on above. Hopefully this will be helpful for someone and I look forward to continuing the series in the near future!
p.s. if anyone can tell me how to directly embed flash I'd appreciate it. The "flash" button doesn't seem to have done the trick.