Menu
CoddyTech

Dinding Menghalangi Kesatria

Termasuk bagian Proyek dalam perjalanan Pygame di Coddy. Pelajaran 24 dari 33.

Kesatria bergerak dengan tombol panah sejauh 3 piksel per frame, dan dinding menghentikannya seperti platform di Moss Caves: bergerak sepanjang sumbu x, dorong keluar dari dinding mana pun yang ditabraknya, lalu lakukan hal yang sama sepanjang sumbu y. Dengan menggerakkan satu sumbu saja setiap kali, kamu bisa mengetahui sisi mana yang ditabraknya.

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

Baca tombol panah setiap frame ke dalam dx dan dy, seperti di Catch the Blocks, lalu berikan dinding ruangan:

keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
    dx = -3
# Lakukan hal yang sama untuk Right, Up, dan Down
knight.move(dx, dy, room.walls)
challenge icon

Tantangan

Sulit

Buat kesatria berjalan dan berhenti saat tertahan dinding.

  1. Tambahkan metode move(dx, dy, blocks) di atas ke Knight.
  2. Setiap frame, atur dx ke -3 dengan tombol Kiri atau ke 3 dengan tombol Kanan, lalu atur dy ke -3 dengan tombol Atas atau ke 3 dengan tombol Bawah, dan ke 0 jika tidak ada tombol yang ditekan.
  3. Lalu panggil knight.move(dx, dy, room.walls).

Tekan tombol “Main” dan berjalanlah menuju dinding: kesatria akan berhenti di sana. Lalu tekan tombol “Periksa”.

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


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

Semua pelajaran di Proyek

Latihan sendiri: Playground Pygame