Creating a Very Simple Platformer

From bricks we built the pyramids

We now have all the pieces for a game: drawing, animation, lists, and keyboard input. In this lesson we put them together into a very simple platformer. It has a floor, a couple of platforms, and a player who can run and jump.

We will build it one step at a time. Only the first step and the final program can be run, because the steps in between are pieces that go inside the program you already have. Those pieces are shown in blocks that cannot be run. If you get stuck, the complete program is at the end.

Step 1: The Player

First we need something to draw. We store everything about the player in variables, created before the loop.

csp
You may also type <- !=>= <= for auto complete.

The player is 20 wide and 30 tall. The floor starts at y = 360. The player’s y is its top edge, so a player standing on the floor has y = 360 - 30 = 330.

Step 2: Running

Add this inside the loop, above the drawing code. It is the same idea as the last lesson.

*csp
You may also type <- !=>= <= for auto complete.

The last two checks keep the player on the canvas. We subtract the width from 400 because x is the player’s left edge.

Step 3: Gravity

Gravity is the same idea as the falling ball in the animation lesson. Each frame, gravity changes the vertical velocity, and the velocity changes the position. Add this next, still inside the loop.

*csp
You may also type <- !=>= <= for auto complete.

If you run the program now, the player falls straight through the floor and off the canvas. We need collision.

Step 4: Landing on the Floor

For now, we handle the floor with a simple rule. If the player’s top is past 330, its feet are in the floor, so we put it back on top and stop the fall. We also remember that the player is standing, because we only want to jump from the ground. This variable, onGround, is created before the loop, next to the other player variables.

*csp
You may also type <- !=>= <= for auto complete.

The rule itself goes inside the loop, right after y ← y + vy.

*csp
You may also type <- !=>= <= for auto complete.

We set onGround to false first, and only switch it to true if we land. That way it is always correct for the current frame.

Step 5: Jumping

A jump is a sudden upward velocity. Up is negative, so we give vy a negative value. This only works when the player is standing, which is what onGround is for. We store whether a jump key is held in jumpHeld, which is created before the loop.

*csp
You may also type <- !=>= <= for auto complete.

This part goes inside the loop, above the gravity code.

*csp
You may also type <- !=>= <= for auto complete.

Gravity then slows the jump down, stops it at the top, and pulls the player back down. A starting speed of 11 with gravity of 0.6 rises about 100 pixels. Try changing both numbers to see how the jump feels.

Step 6: Platforms

A real platformer needs more than a floor. Instead of a special rule for the floor, we can treat the floor as just the first platform in a list. Then one rule works for every platform. We use parallel lists, as we saw in the last lesson. These are created before the loop.

*csp
You may also type <- !=>= <= for auto complete.

Now we can replace the floor rule from Step 4. The rule for landing is: the player lands on a platform if it is falling, it lines up with the platform from side to side, and it was above the platform’s top last frame but has now reached it.

That last part matters. We remember where the player was before moving, in oldY. If we only checked whether the player’s feet are below the platform’s top, the player would be pulled up onto a platform even when walking into it from underneath.

Both oldY and the counter i are created before the loop.

*csp
You may also type <- !=>= <= for auto complete.

Inside the loop, the movement and the landing check now look like this.

*csp
You may also type <- !=>= <= for auto complete.

The first IF checks that the player is falling and overlaps the platform from side to side. The inner IF checks that the player’s feet were above the top before moving, and are at or below it now. When both are true, we place the player on top and stop the fall.

The platforms also need drawing. We use the same kind of loop over the index.

*csp
You may also type <- !=>= <= for auto complete.

The Complete Program

Here is everything together. The comments show where each step went.

csp
You may also type <- !=>= <= for auto complete.

Use the arrow keys or A and D to run, and Up, W, or Space to jump. The first platform is 70 pixels above the floor, which a full jump clears with room to spare. The second is another 70 up, with a 60 pixel gap to cross.

How It Works

Every frame, the program does the same four things in order.

  1. Read the keys and set the horizontal velocity.
  2. Jump if the player asked to and is standing.
  3. Apply gravity, and move the player by its velocity.
  4. Check for landings, and put the player back on top of anything it reached.

Then it draws. Updating first and drawing last is the pattern from the animation lesson.

Because we only check for landing from above, the player can jump up through a platform from underneath and land on top of it. The player also cannot be stopped by the side of a platform. This is a simplification, and it is why this platformer is “very simple.”

Challenges


If you would like to see what is possible with CSP take a look at this platformer.

Try out your own projects here using the CSP sandbox.