Menu
CoddyTech

Mauern halten den Ritter auf

Teil des Abschnitts Projekte der Pygame-Journey von Coddy. Lektion 24 von 33.

Der Ritter bewegt sich mit den Pfeiltasten, 3 Pixel pro Frame, und die Wände halten ihn auf, so wie es die Plattformen in Moss Caves getan haben: Bewege ihn entlang der x-Achse, schiebe ihn aus jeder Wand, die er überlappt, und mache dann dasselbe entlang der y-Achse. Wenn du immer nur eine Achse auf einmal bearbeitest, weißt du, welche Seite er getroffen hat.

def move(self, dx, dy, blocks):
    self.rect.x += dx
    for block in blocks:
        if self.rect.colliderect(block):
            if dx > 0:
                self.rect.right = block.left
            elif dx < 0:
                self.rect.left = block.right
    self.rect.y += dy
    for block in blocks:
        if self.rect.colliderect(block):
            if dy > 0:
                self.rect.bottom = block.top
            elif dy < 0:
                self.rect.top = block.bottom

Lies die Pfeiltasten in jedem Frame in dx und dy ein, wie bei Catch the Blocks, und übergib die Wände des Raums:

keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
    dx = -3
# Rechts, Oben und Unten auf die gleiche Weise
knight.move(dx, dy, room.walls)
challenge icon

Aufgabe

Schwer

Lass den Ritter laufen, wobei ihn die Wände aufhalten.

  1. Gib Knight die oben gezeigte Methode move(dx, dy, blocks).
  2. Setze in jedem Frame dx mit Left auf -3 oder mit Right auf 3 und dy mit Up auf -3 oder mit Down auf 3, sonst auf 0.
  3. Rufe dann knight.move(dx, dy, room.walls) auf.

Drücke „Spielen“ und laufe gegen eine Wand: Der Ritter bleibt daran stehen. Drücke dann „Prüfen“.

Probier es selbst

import pygame

TILE = 48
MAP = [
    "##############",
    "#............#",
    "#.P......K...#",
    "#............#",
    "#....##......D",
    "#....##......#",
    "##.#######.###",
    "#............#",
    "#...S....H...#",
    "##############",
]

pygame.init()
screen = pygame.display.set_mode((672, 480))
pygame.display.set_caption("Rune Keep")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)


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")
door_img = load("dungeon_door.png")
key_img = load("key.png")
slime_img = load("slime.png")
spider_img = load("spider.png")
heart_img = load("heart.png")
empty_img = load("heart_empty.png")
sword_img = load("sword.png")
potion_img = load("potion_red.png")


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


def cell_rect(col, row):
    rect = pygame.Rect(0, 0, 32, 32)
    rect.center = (col * TILE + 24, row * TILE + 24)
    return rect


class Room:
    def __init__(self, lines):
        self.walls = []
        self.start = (72, 72)
        for row, line in enumerate(lines):
            for col, char in enumerate(line):
                if char == "#":
                    self.walls.append(pygame.Rect(col * TILE, row * TILE, TILE, TILE))
                elif char == "P":
                    self.start = cell_rect(col, row).center


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


room = Room(MAP)
knight = Knight(room.start)

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

    for row in range(10):
        for col in range(14):
            screen.blit(floor_img, (col * TILE, row * TILE))
    for wall in room.walls:
        screen.blit(wall_img, wall)
    draw(knight.image, knight.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Alle Lektionen in Projekte

Übe selbstständig: Pygame-Playground