Menu
CoddyTech

Il cavaliere cammina

Fa parte della sezione Progetti del percorso Pygame di Coddy. Lezione 22 di 31.

Il cavaliere parte dalla P della mappa e cammina usando i tasti freccia, 3 pixel per fotogramma.

La sua immagine occupa un’intera casella, 48 per 48, così come gli spazi tra i muri. Un Rect di 48 pixel entrerebbe in uno spazio solo se allineato al pixel esatto. Perciò il Rect del cavaliere è più piccolo della sua immagine: 32 per 32, e l’immagine viene disegnata centrata su di esso. È il Rect a collidere; l’immagine è ciò che vedi.

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

I muri lo fermano come facevano le piattaforme in Moss Caves: si muove lungo l’asse x, viene spinto fuori da ogni muro con cui si sovrappone, poi fa lo stesso lungo l’asse y. Procedere lungo un asse alla volta permette di capire da quale 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
    # poi lo stesso per dy, con bottom e top
challenge icon

Sfida

Difficile
  1. Aggiungi le funzioni draw e cell_rect sopra.
  2. In Room, imposta self.start = (72, 72) prima del ciclo e, per una P, imposta self.start = cell_rect(col, row).center.
  3. Scrivi class Knight(pygame.sprite.Sprite): il suo __init__(self, center) imposta self.image = knight_img e un self.rect di 32 per 32 centrato su center. Assegnagli il metodo move(dx, dy, blocks) qui sopra, con la parte relativa a y.
  4. Crea knight = Knight(room.start) dopo la stanza.
  5. A ogni fotogramma, imposta dx a -3 con la freccia sinistra o a 3 con la freccia destra, dy a -3 con la freccia su o a 3 con la freccia giù (0 altrimenti), poi chiama knight.move(dx, dy, room.walls).
  6. Disegna il cavaliere dopo i muri: draw(knight.image, knight.rect).

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


class Room:
    def __init__(self, lines):
        self.walls = []
        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))


room = Room(MAP)

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)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Progetti

Esercitati da solo: Playground Pygame