Welcome back to this tutorial series on how to write your first platformer in PyGame. This is Part 5 – if you’ve haven’t seen the previous parts it’s best to start at the beginning with Part 1.

A quick recap of what happened in Part 4:

  • we added gravity, making the player character fall down the screen
  • we added jumping when the UP arrow is pressed

In this part of the tutorial we will start adding platforms to the game.

Before we get started, here is the complete code so far:

# import the PyGame library
import pygame
from pygame.locals import *

# initialise PyGame
pygame.init()
pygame.display.set_caption("Platformer")

# settings
HEIGHT = 450
WIDTH = 400
FPS = 60
LEFT_RIGHT_MOVE = 5

# the clock and display surface
FramePerSec = pygame.time.Clock()
displaysurface = pygame.display.set_mode((WIDTH, HEIGHT))

# the Player Sprite
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        # 15,15 is the width and height
        self.surf = pygame.Surface((15, 15))
        self.surf.fill((128,255,40))
        self.rect = self.surf.get_rect()
        self.rect.midbottom = (200, 225)

# visible elements
P1 = Player()
all_sprites = pygame.sprite.Group()
all_sprites.add(P1)

speed_y = 0

# the game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
    displaysurface.fill((0, 0, 0))

    # move the player left/right
    keys = pygame.key.get_pressed()
    if keys[K_LEFT]:
        P1.rect.left -= LEFT_RIGHT_MOVE
    if keys[K_RIGHT]:
        P1.rect.right += LEFT_RIGHT_MOVE

    # stop at the edge
    if P1.rect.left < 0:
        P1.rect.left = 0
    if P1.rect.right > WIDTH:
        P1.rect.right = WIDTH

    # jump
    if keys[K_UP]:
        speed_y = -8

    # gravity
    P1.rect.bottom += speed_y
    speed_y += 0.5

    if P1.rect.bottom > HEIGHT:
        P1.rect.bottom = HEIGHT
        speed_y = 0

    # draw all visible elements
    for entity in all_sprites:
        displaysurface.blit(entity.surf, entity.rect)

    pygame.display.update()
    FramePerSec.tick(FPS)

Adding platform graphics – more Sprites!

Let’s add some platform graphics to the game. Remember how we used a Sprite class to create the player character? Platforms also need to be displayed on the screen, so we are going to use another Sprite class to create them.

Here is the new code for the Platform Sprite:

class Platform(pygame.sprite.Sprite):
    def __init__(self, width, position, colour = (255,0,0)):
        super().__init__()
        self.surf = pygame.Surface((width, 20))
        self.surf.fill(colour)
        self.rect = self.surf.get_rect(center = position)

Notice this line: self.surf = pygame.Surface((width, 20)) – it sets the height of the platform to 20 pixels.

So how to you create a new Platform with this code? Since it’s a Python class you can create new instance of it, and each instance will become a new platform in the game.

The Platform class takes 3 parameters:

  1. The width of the platform, in pixels
  2. The position of the platform – this is a (x, y) coordinate pair
  3. Optionally a third parameter with the colour of the platform. This is a (red, green, blue) tuple (more on tuples below!). If you don’t pick a colour then red will be used by default.

With this in mind you create new platforms by using code like this:

platform_1 = Platform(100, (200, 330))
platform_2 = Platform(50, (150, 400))

These lines create 2 platforms – the first is 100 pixels wide and positioned at x=200, y=300. The second is 50 pixels wide and positioned at x=150, y=400.

To draw the platforms on the screen you also need to make sure they are included in the game loop’s drawing code. To do this you would add the platform sprites to the all_sprites collection:

all_sprites.add(platform_1)
all_sprites.add(platform_2)

Change your game code to include these extra lines, highlighted in bold green:

# the Player Sprite
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        # 15,15 is the width and height
        self.surf = pygame.Surface((15, 15))
        self.surf.fill((128,255,40))
        self.rect = self.surf.get_rect()
        self.rect.midbottom = (200, 225)

# the Platform Sprite
class Platform(pygame.sprite.Sprite):
    def __init__(self, width, position, colour = (255,0,0)):
        super().__init__()
        self.surf = pygame.Surface((width, 20))
        self.surf.fill(colour)
        self.rect = self.surf.get_rect(center = position)

platform_1 = Platform(100, (200, 330))
platform_2 = Platform(50, (150, 400))

# visible elements
P1 = Player()
all_sprites = pygame.sprite.Group()
all_sprites.add(P1)
all_sprites.add(platform_1)
all_sprites.add(platform_2)

Once you’ve done that your game screen should look like this:

A quick word about tuples

You might have noticed some odd looking numbers in brackets a few times in the code, like the position of the platforms as (200, 330) for example, or the colour values that look like (255, 0, 0). These lists of numbers are grouped together using brackets. These things are called tuples. They are a key feature of the Python programming language and it’s useful to know more about them.

In Python when you have some numbers or other values that belong together, you can group them together as a list. You can use them in your code as a single value which is more convenient and easier to write.

One example is setting the position of the Player. The code looks like this:

self.rect.midbottom = (200, 225)

midbottom is a point on the screen and it needs an x and a y coordinate. Instead of setting each value separately the code uses a tuple, which combines the x and y coordinates into a single variable.

Similarly to set the colour of the player’s character we use this code:

self.surf.fill((128,255,40))

The colour needs 3 values – the Red, Green, Blue components – and instead of setting each one separately we can use a tuple (128, 255, 40) instead.

The tuple is always wrapped in its own set of brackets, so here we end up with double pairs of brackets. The first set is for the fill() command, the second set is for the colour tuple.

Next Steps

Now that you have added a few platforms to the game, experiment with the platform code to create a level that looks good to you. Make sure there are enough platforms to fill the screen from top to bottom, and that they seem within reach of your jumping player character.

For example after some tweaking I’ve come up with this level design:

I’m looking forward to seeing what you can come up with!

In the next tutorial (not written yet!) we will look at making the player character land on the platforms. Keep checking back!