Skip to content

157. 2D platform game #2 – How it works

September 10, 2014

Before I get into detail, I’ll just say that this is not intended to be the ultimate way to build a sidescrolling game.  Like you (probably), I am an enthusiastic hobby programmer, and while I have been programming for many years, I cannot guarantee I will always think of the best way to do things. And this is my first side scroller. Having said that, let’s get started.

So suppose I have a rough sketch of a platform game level – how is it going to work in practice? What is the gameplay, and how will my player move around and interact with objects in the game?

Game objects

I’m using a tiled map (ie a map with lots of little squares), and each tile can hold either one object or nothing.

And I’m going to have three types of object.

 photo Grass_zpsfd9601e0.png The most basic objects are the surface and walls, like grass or brick blocks. They fill a whole tile, and the player can’t enter these tiles at all.
 photo flame_zpsb7ca0353.png There are other static (non moving) objects like lights, that a player can walk past, but there is no interaction, ie nothing happens.
 photo Coin_zps481b58e1.png Finally, there are the objects which interact with and affect the player. They can have a whole range of behaviours, including increasing or reducing health, being collectible, etc.

 

The player

I’m going to use the little dude from the Platformer Art library

I need to animate him, but I’ll get to that later.

Player movement

The player can walk left and right, jump up, and leap (jump up and sideways) left or right.

I could use a joystick for this, but I prefer to keep things simple and use touch. So I’m going to use finger swipes

  • sideways – to walk left or right (multiple swipes to speed up/down)
  • up – to jump up in the air
  • diagonally up (left or right) to leap to the left or right

 

Collisions

Any platform game is all about collisions.

Colliding with blocks

The player walks and jumps, and may collide with blocks on any side of him. If he jumps up on top of a block, he will also collide with it when he lands on it.

Colliding with blocks is quite easy to manage, because they take up a whole tile. The fastest way to do this is to have a 2D table the same size as the map, with a value for each tile (say 0 for blank, 1 for block). When we move the player, we can figure out which tile he is moving into (maybe two tiles, if the player is moving diagonally or is between two tiles), and look up its value in the table, which is quicker than checking for a collision.

While this is easy so far, you do need to think about things like what happens when the player lands on top of two tiles (ie partly on each). Suppose only one pixel of the player is on a block tile, and the rest of the player is hanging over an empty tile, which looks a bit silly. Do you need a minimum number of pixels to be on a block, to avoid falling off? Well, to keep it simple, I didn’t bother with anything fancy – one pixel is enough (hey, this is a game!).

Colliding with (interactive) objects

The player can also collide with lots of other objects, such as coins, all the bad guys, etc. This is where you can get into trouble, and I spent a lot of time figuring this out.

First, the objects are all different shapes and sizes. What most games do is to use a rectangle for each object, and then to see if two objects A and B collide, you only need to check if their rectangles overlap. It is a little easier if the rectangles are not rotated, ie the sides are always parallel with the floor and walls. Then they are known as AABBs (Axis-Aligned-Bounding Boxes). For now, I am using AABBs.

Overlapping AABBs require four fairly obvious tests (all of which must be true) for two rectangles called A and B

  • the left of A is to the left of the right of B
  • the right of A is to the right of the left of B
  • the bottom of A is below the top of B
  • the top of A is above the bottom of B

Here is my code. I’ve actually written it the other way round, testing if each of the four tests is NOT true. If any of them is not true, then the objects are not overlapping.

function SS_ObjectsOverlap(a,b) --a,b are vec4(x,y,w/2,h/2)
  return not (a.x-a.z>=b.x+b.z or a.x+a.z<=b.x-b.z
  or a.y-b.w>=b.y+b.w*m or a.y+a.w<=b.y-b.w)
end

It’s a bit embarrassing admitting I wrote it this way thinking it was faster, because only one “or” test needed to fail to show the objects didn’t overlap. But this is actually exactly the same as having four “and” tests that must all be true, because as soon as one is false, the overlapping is false. What makes it worse is that I am professionally trained to think logically. Fail!

Your next problem is figuring out what rectangle to use for each object. For example, the player only takes up the middle of the image he comes in. If we define his rectangle as the whole image, collisions will seem to be happening when nothing is touching. So it is better to define a smaller rectangle that roughly covers just the actual player. The same goes for any other object that needs a collision rectangle.

Warning the player of new objects

I actually needed a second type of collision. I wanted to warn the player (just once) when a new type of object is near. To do this, I need to detect when the player is close to colliding with that object. This means just using a much bigger rectangle, and showing the message if a “collision” occurs. So now I have two rectangles for each object, one for warnings, and one for actual collisions.

I’ll show how I use these later.

 

Killing the bad guys

I thought about how to do this. Using guns can make it more visually fun, but unless the bad guys jump and dodge, they are going to be sitting ducks. And making them jump and dodge without hitting any objects requires additional programming.

So in this version, I’m just going to program the bad guys to die when you jump on them.

Advertisement

From → Games, Programming

One Comment
  1. Anonymous permalink

    L

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: