La llave y la puerta
Parte de la sección Proyectos del Journey de Pygame de Coddy. Lección 23 de 31.
La puerta de la pared derecha está cerrada con llave. El caballero recoge la llave al pasar por encima y, con la llave, la puerta se abre cuando la toca.
Una puerta cerrada con llave es un obstáculo más para el caballero. Un método de Room proporciona la lista de Rects que lo detienen:
def blocks(self):
if self.door_open:
return self.walls
return self.walls + [self.door]Hay una particularidad al tocar la puerta: move empuja al caballero fuera de ella en cada fotograma, así que su Rect nunca se superpone a la puerta. knight.rect.inflate(8, 8) es una copia de su Rect ampliada en 4 píxeles por cada lado, y esa copia sí se superpone a la puerta contra la que está apoyado.
if room.has_key and knight.rect.inflate(8, 8).colliderect(room.door):
room.door_open = TrueMás allá de la puerta abierta está el borde de la ventana, así que mantén al caballero dentro con clamp_ip. En una lección posterior, la puerta llevará a la siguiente habitación. Muestra la llave en la parte superior mientras la lleva.
Desafío
Intermedio- En
Room, estableceself.has_key = Falseyself.door_open = False. UnaKestableceself.key = cell_rect(col, row); unaDestableceself.dooren el Rect de 48 por 48 de su baldosa. - Añade el método
blocksanterior y mueve al caballero conknight.move(dx, dy, room.blocks()). - Después de moverlo:
knight.rect.clamp_ip(screen.get_rect()); cuando no tenga una llave y toqueroom.key, estableceroom.has_key = True; después, abre la puerta como se indicó anteriormente. - Dibuja la puerta con
screen.blit(door_img, room.door)mientras esté cerrada, la llave condraw(key_img, room.key)hasta que la recoja ykey_imgen(136, 6)mientrasroom.has_keysea verdadero.
Pruébalo tú mismo
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
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
room = Room(MAP)
knight = Knight(room.start)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
dx = -3
if keys[pygame.K_RIGHT]:
dx = 3
if keys[pygame.K_UP]:
dy = -3
if keys[pygame.K_DOWN]:
dy = 3
knight.move(dx, dy, room.walls)
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()
Todas las lecciones de Proyectos
Practica por tu cuenta: Playground de Pygame