Menu
CoddyTech

O Cavaleiro Caminha

Parte da seção Projetos do Journey de Pygame da Coddy. Lição 22 de 31.

O cavaleiro começa no P do mapa e anda usando as teclas de seta, 3 pixels por quadro.

A imagem dele ocupa um bloco inteiro, 48 por 48, assim como os espaços entre as paredes. Um Rect de 48 pixels caberia em um espaço somente quando estivesse alinhado ao pixel exato. Então, o Rect do cavaleiro é menor que a imagem dele, 32 por 32, e a imagem é desenhada centralizada nele. O Rect é o que colide; a imagem é o que você vê.

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

As paredes o detêm como as plataformas faziam em Moss Caves: mova ao longo de x, empurre-o para fora de qualquer parede com a qual ele se sobreponha e, em seguida, faça o mesmo ao longo de y. Fazer um eixo de cada vez indica de que lado ele bateu.

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
    # depois, faça o mesmo para dy, com bottom e top
challenge icon

Desafio

Difícil
  1. Adicione as funções draw e cell_rect acima.
  2. Em Room, defina self.start = (72, 72) antes do loop e, para um P, defina self.start = cell_rect(col, row).center.
  3. Escreva class Knight(pygame.sprite.Sprite): o método __init__(self, center) define self.image = knight_img e um self.rect de 32 por 32 centralizado em center. Adicione o método move(dx, dy, blocks) acima, incluindo a parte do eixo y.
  4. Crie knight = Knight(room.start) depois da sala.
  5. A cada quadro, defina dx como -3 com a tecla Left ou 3 com a tecla Right, e dy como -3 com a tecla Up ou 3 com a tecla Down (0 caso contrário); em seguida, chame knight.move(dx, dy, room.walls).
  6. Desenhe o cavaleiro depois das paredes: draw(knight.image, knight.rect).

Experimente você mesmo

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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Projetos

Pratique por conta própria: Playground de Pygame