Menu
CoddyTech

Duvarlar Şövalyeyi Durdurur

Coddy'nin Pygame Journey'sinin Projeler bölümünün bir parçası. Ders 24 / 33.

Şövalye ok tuşlarıyla kare başına 3 piksel yürür ve duvarlar, Moss Caves'teki platformların yaptığı gibi onu durdurur: x boyunca ilerle, iç içe geçtiği duvarlardan dışarı it, sonra aynısını y boyunca yap. Her seferinde tek bir eksende ilerlemek, hangi tarafa çarptığını anlamanı sağlar.

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

Catch the Blocks'taki gibi, her karede ok tuşlarını dx ve dy değişkenlerine oku ve odanın duvarlarını aktar:

keys = pygame.key.get_pressed()
dx = 0
dy = 0
if keys[pygame.K_LEFT]:
    dx = -3
# Sağ, Yukarı ve Aşağı için de aynı şekilde
knight.move(dx, dy, room.walls)
challenge icon

Görev

Zor

Şövalyeyi duvarların durduracağı şekilde yürüt.

  1. Knight sınıfına yukarıdaki move(dx, dy, blocks) yöntemini ekle.
  2. Her karede, Sol tuşuna basıldığında dx değerini -3, Sağ tuşuna basıldığında 3 yap; aksi hâlde 0 yap. Yukarı tuşuna basıldığında dy değerini -3, Aşağı tuşuna basıldığında 3 yap; aksi hâlde 0 yap.
  3. Ardından knight.move(dx, dy, room.walls) çağrısını yap.

“Oyna” düğmesine bas ve bir duvara doğru yürü: şövalye duvara çarpınca durur. Ardından “Kontrol et” düğmesine bas.

Kendin dene

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

Projeler bölümündeki tüm dersler

Kendi başına pratik yap: Pygame playground