Saturday, 18 July 2026

Building an A Level Platform Game Project — Part 3: Adding Gravity and Jumping

 


Building an A Level Platform Game Project — Part 3: Adding Gravity and Jumping

In Part 1, we planned the platform game and set realistic success criteria.

In Part 2, we created the first working prototype: a game window, a visible player, left and right movement, frame rate control and screen boundary checks.

At that point, the game was visible and interactive, but it was not really a platform game yet.

A player sliding left and right across the screen is a start. But a platform game needs vertical movement. It needs the player to fall, jump, land and respond to gravity.

This is where the project starts to become much more interesting technically.

Adding gravity and jumping introduces some important programming ideas:

  • velocity
  • acceleration
  • game physics
  • state checking
  • keyboard input
  • conditions
  • testing awkward cases
  • preventing repeated jumping in mid-air

It also gives students a proper programming problem to solve, not just a drawing exercise.

Why Gravity Makes the Game Feel Real

In a simple game, the player’s position is controlled by x and y coordinates.

In Part 2, we changed the x-coordinate to move the player left and right.

Now we need to change the y-coordinate as well.

This is where students often meet one of the first confusing ideas in game programming: screen coordinates do not behave like a normal maths graph.

On most screens:

  • x increases as you move right
  • y increases as you move down
  • y decreases as you move up

So when the player falls, the y-coordinate increases.

When the player jumps, the y-coordinate decreases.

This feels backwards at first, but students soon get used to it.

The Aim for Part 3

The target for this stage is:

Add gravity so the player falls downwards, add jumping so the player can move upwards, and prevent the player from jumping again while already in the air.

By the end of this stage, the player should be able to:

  • move left and right
  • stand on the ground
  • jump when the space bar is pressed
  • rise into the air
  • slow down
  • fall back down
  • land on the ground
  • avoid repeated jumping while in the air

This is a major step forward.

The game will still not have platforms yet. That comes in Part 4.

For now, we will use the bottom of the screen as the ground.

Thinking About Vertical Velocity

In Part 2, movement was simple.

If the right arrow was pressed:

player_x += player_speed

If the left arrow was pressed:

player_x -= player_speed

Jumping is more complicated because it changes over time.

When the player first jumps, they move upwards quickly. Then gravity slows them down. Eventually they stop rising and begin to fall.

This means we need a vertical velocity.

A velocity is a speed in a particular direction.

For the player, we can create a variable:

player_y_velocity = 0

This will control how much the player’s y-position changes each frame.

If the vertical velocity is positive, the player moves down.

If the vertical velocity is negative, the player moves up.

That is because screen y-coordinates increase as you move down.

Adding Gravity

Gravity can be represented by increasing the vertical velocity each frame.

For example:

gravity = 0.5
player_y_velocity += gravity
player_y += player_y_velocity

This means the player falls faster and faster.

At first, the vertical velocity may be 0.

After one frame, it becomes 0.5.
Then 1.0.
Then 1.5.
Then 2.0.

This creates acceleration.

The player does not simply fall at one fixed speed. The fall becomes faster over time, which feels more natural.

This is a very useful teaching point because it connects programming with physics.

Creating a Ground Level

Before we add platforms, we need somewhere for the player to land.

A simple approach is to define the ground as a y-coordinate near the bottom of the screen.

For example:

GROUND_LEVEL = 540

If the player is 60 pixels tall, and the screen height is 600 pixels, then placing the player’s top-left y-coordinate at 540 means the bottom of the player is at 600.

So the player stands exactly on the bottom of the screen.

We can check if the player has fallen below the ground:

if player_y > GROUND_LEVEL:
    player_y = GROUND_LEVEL
    player_y_velocity = 0

This prevents the player falling forever.

It also resets the vertical velocity when the player lands.

Adding the Jump

To make the player jump, we give the vertical velocity a negative value.

For example:

player_y_velocity = -12

This moves the player upwards because it reduces the y-coordinate.

The number controls the strength of the jump.

A larger negative number makes the player jump higher.
A smaller negative number makes the player jump lower.

For example:

jump_strength = -12

Then, when the player presses space:

if keys[pygame.K_SPACE]:
    player_y_velocity = jump_strength

This seems simple, but it creates a problem.

The Infinite Jump Problem

If we use the code above, the player may be able to jump again and again while already in the air.

This is sometimes called infinite jumping.

The player can keep pressing space and fly upwards forever.

That might be useful in a different type of game, but it is not what we want in a normal platform game.

We need the program to know whether the player is on the ground.

We can use a Boolean variable:

on_ground = True

A Boolean can only be True or False.

The player should only be allowed to jump if on_ground is True.

For example:

if keys[pygame.K_SPACE] and on_ground:
    player_y_velocity = jump_strength
    on_ground = False

Then, when the player lands:

if player_y > GROUND_LEVEL:
    player_y = GROUND_LEVEL
    player_y_velocity = 0
    on_ground = True

This is an important moment in the project.

The student is no longer just moving a shape. They are managing the state of the player.

The Updated Prototype Code

At the end of Part 3, the prototype might look like this:

import pygame

pygame.init()

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
GROUND_LEVEL = 540

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("Escape the Platforms")

clock = pygame.time.Clock()

player_x = 100
player_y = GROUND_LEVEL
player_width = 40
player_height = 60
player_speed = 5

player_y_velocity = 0
gravity = 0.5
jump_strength = -12
on_ground = True

running = True

while running:
    clock.tick(60)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()

    # Horizontal movement
    if keys[pygame.K_LEFT]:
        player_x -= player_speed

    if keys[pygame.K_RIGHT]:
        player_x += player_speed

    # Jumping
    if keys[pygame.K_SPACE] and on_ground:
        player_y_velocity = jump_strength
        on_ground = False

    # Apply gravity
    player_y_velocity += gravity
    player_y += player_y_velocity

    # Ground collision
    if player_y > GROUND_LEVEL:
        player_y = GROUND_LEVEL
        player_y_velocity = 0
        on_ground = True

    # Screen boundary checks
    if player_x < 0:
        player_x = 0

    if player_x + player_width > SCREEN_WIDTH:
        player_x = SCREEN_WIDTH - player_width

    # Draw everything
    screen.fill((255, 255, 255))

    pygame.draw.rect(
        screen,
        (0, 0, 255),
        (player_x, player_y, player_width, player_height)
    )

    pygame.draw.line(
        screen,
        (0, 0, 0),
        (0, GROUND_LEVEL + player_height),
        (SCREEN_WIDTH, GROUND_LEVEL + player_height),
        3
    )

    pygame.display.update()

pygame.quit()

This is still a simple prototype, but it now behaves much more like a game.

The player can move.
The player can jump.
The player falls because of gravity.
The player lands on the ground.
The player cannot repeatedly jump in mid-air.

That is a very important development stage.

Why We Draw a Ground Line

In the example code, a black line is drawn at the bottom of the screen:

pygame.draw.line(
    screen,
    (0, 0, 0),
    (0, GROUND_LEVEL + player_height),
    (SCREEN_WIDTH, GROUND_LEVEL + player_height),
    3
)

This is mainly for visual clarity.

It helps the student see where the ground is.

At this stage, the ground is not a proper platform. It is simply a boundary that stops the player falling off the screen.

In Part 4, we will replace this simple ground idea with proper platforms.

Testing Gravity and Jumping

This stage needs proper testing.

Students should not simply say “jumping works”.

They should test specific behaviours.

Test NumberTestExpected ResultActual ResultPass/Fail
1Run the programPlayer appears standing on the groundPlayer appears on the groundPass
2Press left arrowPlayer moves leftPlayer moves leftPass
3Press right arrowPlayer moves rightPlayer moves rightPass
4Press space while on groundPlayer jumps upwardsPlayer jumps upwardsPass
5Release space after jumpingPlayer continues moving according to velocity and gravityPlayer rises then fallsPass
6Press space repeatedly in the airPlayer does not keep jumping upwardsPlayer cannot double jumpPass
7Player falls back to groundPlayer lands and stops fallingPlayer lands correctlyPass
8Hold left arrow while jumpingPlayer moves left in the airPlayer moves left while airbornePass
9Hold right arrow while jumpingPlayer moves right in the airPlayer moves right while airbornePass
10Move to screen edge while jumpingPlayer stays within the screenPlayer remains inside screenPass

This table creates useful evidence for the project.

It also shows that the student has thought about normal tests and more awkward cases.

Linking Back to Success Criteria

In Part 1, we created success criteria for the project.

This stage helps meet several of them:

  • The player falls when not standing on a platform.
  • The player can jump from the ground.
  • The player cannot repeatedly jump while already in the air.
  • The player lands without falling through the ground.
  • The player can move left and right while jumping.
  • The player cannot move beyond the edge of the game screen.

This is why success criteria are so valuable.

They allow the student to show measurable progress.

A development log could say:

This stage successfully added gravity and jumping. Testing showed that the player could jump from the ground, fall back down and land correctly. A Boolean variable was added to prevent the player from repeatedly jumping while in the air.

That is much stronger than simply writing:

I added jumping.

Common Bugs Students May Meet

This stage often produces interesting bugs.

That is good.

A Level projects need evidence of problems being found and solved.

Bug 1: The Player Falls Through the Ground

This may happen if the ground check is missing or incorrect.

For example, if the program checks:

if player_y == GROUND_LEVEL:

this may fail because the player might move from just above the ground to just below the ground in one frame.

It is safer to check:

if player_y > GROUND_LEVEL:

or sometimes:

if player_y >= GROUND_LEVEL:

This is a useful programming lesson.

Exact equality is not always the best test when movement is changing every frame.

Bug 2: The Player Can Jump Forever

This usually happens if the program does not check whether the player is on the ground.

The solution is to use a variable such as:

on_ground

and only allow jumping when this is True.

Bug 3: The Jump Is Too High or Too Low

This is controlled by the jump strength and gravity.

For example:

gravity = 0.5
jump_strength = -12

Students can experiment with these values.

A smaller gravity value makes the player float for longer.
A larger gravity value pulls the player down faster.
A more negative jump strength creates a higher jump.
A less negative jump strength creates a smaller jump.

This gives a good opportunity for testing and user feedback.

The student could ask a user:

Does the jump feel too high, too low or about right?

Then they can adjust the values and record the improvement.

Bug 4: The Player Appears to Sink Into the Ground

This may happen if the ground level has been calculated incorrectly.

The important question is:

Does player_y represent the top of the player or the bottom of the player?

In our example, player_y represents the top-left corner of the player rectangle.

That means the bottom of the player is:

player_y + player_height

This distinction becomes very important when we add platforms.

Why This Is Good Evidence for A Level

Gravity and jumping create a strong section for the project write-up because the student can explain the algorithm.

They can describe:

  • why a vertical velocity variable was needed
  • how gravity changes the velocity each frame
  • why a negative velocity moves the player upwards
  • how the program detects landing
  • why a Boolean variable prevents repeated jumping
  • how the values for gravity and jump strength were tested

This is exactly the kind of thinking that should appear in a strong programming project.

The final program matters, but the explanation of the development process matters too.

Improving the Code Structure

At this stage, the code is still manageable.

However, we can already see that it is becoming more complex.

The player now has:

  • x-position
  • y-position
  • width
  • height
  • horizontal speed
  • vertical velocity
  • jump strength
  • ground state

Later, the player may also have:

  • lives
  • score
  • direction
  • animation state
  • collision rectangle
  • health
  • current level

This is a good point to discuss whether a class may eventually be useful.

A Player class could store the player’s data and methods in one place.

For example, it might eventually include:

class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 40
        self.height = 60
        self.speed = 5
        self.y_velocity = 0
        self.on_ground = True

    def move(self, keys):
        pass

    def jump(self):
        pass

    def apply_gravity(self):
        pass

    def draw(self, screen):
        pass

Students do not need to do this immediately, but they should be aware of why it might help.

A strong project can show how the code was improved as complexity increased.

Should the Player Be Able to Move in the Air?

In the current version, the player can move left and right while jumping.

That is common in many platform games.

However, it is a design decision.

Some games give the player a lot of control in the air. Others make jumping more rigid and realistic.

Students can think about this as part of their evaluation.

Questions to consider:

  • Should the player be able to change direction while in the air?
  • Should air movement be slower than ground movement?
  • Should the game feel realistic or arcade-like?
  • What does the target user prefer?

This is a nice example of how programming choices connect to user experience.

Adding Debug Information

During development, it can be useful to display values on the screen or print them to the console.

For example, students might print:

print(player_y, player_y_velocity, on_ground)

This helps them see what is happening when the player jumps and lands.

However, debug output should usually be removed or hidden in the final version.

Students can mention this in their documentation:

I used printed debug values to check the player’s y-coordinate, vertical velocity and ground state while testing the jump algorithm. This helped identify when the player was landing and when the on_ground variable changed.

That is useful evidence of debugging.

Practical Task for Students

Before moving on to platforms, students should complete this task.

Part 3 Student Task

Add gravity and jumping to your platform game prototype.

Your program should include:

  1. A vertical velocity variable.
  2. A gravity value.
  3. A jump strength value.
  4. A ground level.
  5. A Boolean variable to record whether the player is on the ground.
  6. A jump controlled by the space bar or another chosen key.
  7. A check to stop the player falling through the ground.
  8. A check to stop repeated jumping in mid-air.
  9. A test table for gravity and jumping.
  10. Screenshots or short video evidence of the player jumping and landing.

Extension Task

Improve the jumping system by adding one of the following:

  • a different jump height
  • a maximum falling speed
  • a double jump as an intentional feature
  • a smoother jump animation
  • reduced air control
  • a sound effect when jumping
  • a debug display showing vertical velocity

Students should only attempt the extension once the basic jump works correctly.

Development Log Example

A good development log entry for this stage might look like this:

Development Stage

Adding gravity and jumping.

Aim

To make the player fall under gravity, jump when the space bar is pressed and land correctly on the ground.

What Was Added

  • vertical velocity variable
  • gravity variable
  • jump strength variable
  • ground level
  • on_ground Boolean variable
  • jump input using the space bar
  • landing check
  • testing for repeated jumping

Problems Found

  • The player initially kept jumping while already in the air.
  • The player sometimes moved slightly below the ground before being reset.
  • The jump height needed adjusting to feel natural.

Changes Made

  • Added an on_ground variable to prevent repeated jumping.
  • Reset the player’s y-position to the ground level after landing.
  • Adjusted gravity and jump strength values after testing.

Evidence Collected

  • screenshot of the player standing on the ground
  • screenshot of the player in the air
  • test table showing jump behaviour
  • code section showing gravity and jump logic
  • notes explaining how the infinite jump bug was fixed

This kind of evidence is valuable because it shows a real development process.

Final Thoughts: The Game Is Starting to Behave

At the end of Part 3, the game still looks simple.

The player may still be just a rectangle.
There may be no platforms yet.
There may be no enemies, collectables or levels.

But something important has changed.

The game now has behaviour.

The player can move, jump, fall and land. The program now includes a simple physics system. It uses velocity, gravity and state checking. It has already produced bugs that need proper solutions.

That is exactly what makes it a useful A Level project.

A platform game becomes interesting not because of the graphics, but because of the rules underneath.

In the next article, we will add one of the most important and challenging parts of the project: platforms and collision detection.

That is where the player stops jumping on an imaginary ground and starts interacting with the world of the game.

No comments:

Post a Comment