Menu
CoddyTech

Run Animation

Part of the Game Rules section of Coddy's Pygame journey. Lesson 25 of 29.

The runner glides. The pack has a second picture of the same hero, player_walk.png, with its legs apart. Swapping between the two pictures makes it run.

Keep both in a list and count frames. self.step // 8 goes up by 1 every 8 frames, and % 2 turns that into 0, 1, 0, 1:

if self.rect.bottom == GROUND_Y:
    self.step += 1
    self.image = self.frames[self.step // 8 % 2]
else:
    self.image = self.frames[1]

8 frames a picture is about seven steps a second at 60 frames a second. Fewer frames make it run faster, more make it slow.

In the air there is nothing to run on, so the runner holds one picture until it lands. Load both pictures once, in __init__, and swap which one self.image names: the group or the blit draws whatever it names.

challenge icon

Challenge

Medium
  1. Load player.png and player_walk.png into a list, self.frames, with self.image starting as the first and self.step = 0.
  2. In update(), on the ground, count a step and show self.frames[self.step // 8 % 2].
  3. In the air, show self.frames[1].

Try it yourself

import pygame

pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()

SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1


class Runner(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.image.load("assets/images/player.png").convert_alpha()
        self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
        self.vy = 0

    def jump(self):
        if self.rect.bottom == GROUND_Y:
            self.vy = -16

    def update(self):
        self.vy += GRAVITY
        self.rect.y += self.vy
        if self.rect.bottom >= GROUND_Y:
            self.rect.bottom = GROUND_Y
            self.vy = 0


runner = Runner()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
            runner.jump()

    runner.update()

    screen.fill(SKY)
    pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
    screen.blit(runner.image, runner.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in Game Rules

Practice on your own: Pygame playground