Kunci dan Pintu
Termasuk bagian Proyek dalam perjalanan Pygame di Coddy. Pelajaran 23 dari 31.
Pintu di dinding kanan terkunci. Kesatria mengambil kunci dengan berjalan melewatinya, lalu pintu terbuka saat ia menyentuhnya sambil membawa kunci.
Pintu yang terkunci menjadi satu hal lagi yang menghalangi kesatria. Sebuah method pada Room memberikan daftar Rect yang menghalanginya:
def blocks(self):
if self.door_open:
return self.walls
return self.walls + [self.door]Ada kendala saat menyentuh pintu: move mendorong kesatria menjauh darinya pada setiap frame, jadi Rect-nya tidak pernah bertumpang tindih dengan pintu. knight.rect.inflate(8, 8) adalah salinan Rect-nya yang diperbesar 4 piksel di setiap sisi, dan salinan itu bertumpang tindih dengan pintu yang sedang ia hadapi.
if room.has_key and knight.rect.inflate(8, 8).colliderect(room.door):
room.door_open = TrueDi balik pintu yang terbuka ada tepi jendela, jadi jaga kesatria tetap di dalam dengan clamp_ip. Pada pelajaran berikutnya, pintu itu akan mengarah ke ruangan berikutnya. Tampilkan kunci di bagian atas saat ia membawanya.
Tantangan
Sedang- Di
Room, tetapkanself.has_key = Falsedanself.door_open = False.Kmenetapkanself.key = cell_rect(col, row);Dmenetapkanself.doorke Rect berukuran 48 kali 48 dari petaknya. - Tambahkan method
blocksdi atas dan gerakkan knight denganknight.move(dx, dy, room.blocks()). - Setelah bergerak:
knight.rect.clamp_ip(screen.get_rect()); saat knight belum memiliki kunci dan menyentuhroom.key, tetapkanroom.has_key = True; lalu buka pintu seperti di atas. - Gambar pintu dengan
screen.blit(door_img, room.door)saat pintu tertutup, kunci dengandraw(key_img, room.key)hingga diambil, dankey_imgdi(136, 6)saatroom.has_keybernilai true.
Coba sendiri
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()
Semua pelajaran di Proyek
Latihan sendiri: Playground Pygame