Menu
CoddyTech

I muri fermano il cavaliere

Fa parte della sezione Progetti del percorso Pygame di Coddy. Lezione 24 di 33.

Il cavaliere cammina con i tasti freccia, di 3 pixel per fotogramma, e i muri lo fermano come facevano le piattaforme in Moss Caves: si sposta lungo x, viene spinto fuori da ogni muro che interseca, poi fa lo stesso lungo y. Procedere su un asse alla volta ti permette di capire da che lato ha urtato.

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

Leggi le frecce a ogni fotogramma in dx e dy, come in Catch the Blocks, e passa i muri della stanza:

keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
    dx = -3
# Destra, Su e Giù allo stesso modo
knight.move(dx, dy, room.walls)
challenge icon

Sfida

Difficile

Fai camminare il cavaliere, fermandolo contro i muri.

  1. Aggiungi a Knight il metodo move(dx, dy, blocks) riportato sopra.
  2. A ogni fotogramma, imposta dx su -3 con Left o su 3 con Right, e dy su -3 con Up o su 3 con Down, altrimenti su 0.
  3. Poi chiama knight.move(dx, dy, room.walls).

Premi «Gioca» e cammina contro un muro: il cavaliere si ferma. Poi premi «Verifica».

Provalo tu

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()

Tutte le lezioni di Progetti

Esercitati da solo: Playground Pygame