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.
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.
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.
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.
The rule itself goes inside the loop, right after y ← y + vy.
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.
This part goes inside the loop, above the gravity code.
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.
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.
Inside the loop, the movement and the landing check now look like this.
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.
The Complete Program
Here is everything together. The comments show where each step went.
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.
- Read the keys and set the horizontal velocity.
- Jump if the player asked to and is standing.
- Apply gravity, and move the player by its velocity.
- 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
- Add a third platform, and then a fourth. You only change the four platform lists.
- Add a coin from a circle. When the player’s rectangle overlaps it, stop drawing it and
add one to a score shown with
DRAW_TEXT. - Add lava. Draw a red rectangle, and put the player back at the start if it touches the lava.
- Make short taps produce short jumps. When the jump key is released while the player is still rising, add extra gravity.
- Add a goal door, and show a message when the player reaches it.
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.