Menu
CoddyTech

Walking

Lesson 3 of 20 in Coddy's Pygame Project: Hold the Keep course.

pygame.key.get_pressed() says which keys are held down right now. Read it every frame and the knight walks for as long as an arrow is held, without waiting for key repeats.

Give the knight a speed and a move method, so the rules of how it walks live with the knight:

def move(self, keys):
    if keys[pygame.K_LEFT]:
        self.rect.x -= self.speed
    if keys[pygame.K_RIGHT]:
        self.rect.x += self.speed
    self.rect.clamp_ip(courtyard)

Four separate ifs, not elif: with Up and Right held together the knight walks diagonally.

clamp_ip moves a Rect back inside another Rect if it has left it, so the knight stops at the walls. The _ip means in place: it changes self.rect itself instead of returning a new Rect.

challenge icon

Challenge

Easy
  1. In Knight.__init__ set self.speed = 3.
  2. Write move(self, keys): each arrow key moves the rect by self.speed, then self.rect.clamp_ip(courtyard).
  3. In the game loop, before drawing, call knight.move(pygame.key.get_pressed()).

Try it yourself

import pygame

WIDTH, HEIGHT = 720, 480
TILE = 48

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Hold the Keep")
clock = pygame.time.Clock()


def load(name):
    return pygame.image.load("assets/images/" + name).convert_alpha()


floor_img = load("floor.png")
wall_img = load("wall.png")
knight_img = load("knight.png")

courtyard = pygame.Rect(TILE, TILE, WIDTH - 2 * TILE, HEIGHT - 2 * TILE)
background = pygame.Surface((WIDTH, HEIGHT))
for row in range(HEIGHT // TILE):
    for col in range(WIDTH // TILE):
        x = col * TILE
        y = row * TILE
        if courtyard.collidepoint(x, y):
            background.blit(floor_img, (x, y))
        else:
            background.blit(wall_img, (x, y))


def draw(image, center):
    screen.blit(image, image.get_rect(center=center))


class Knight(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = knight_img
        self.rect = pygame.Rect(0, 0, 24, 24)
        self.rect.center = courtyard.center


knight = Knight()

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

    screen.blit(background, (0, 0))
    draw(knight.image, knight.rect.center)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

All lessons in Pygame Project: Hold the Keep

Practice on your own: Pygame playground