Menu
CoddyTech

Hiệp sĩ

Thuộc phần Dự án trong hành trình Pygame của Coddy. Bài học 23 trên 33.

Kỵ sĩ bắt đầu ở ô P trên bản đồ.

Hình của kỵ sĩ chiếm trọn một ô, kích thước 48 × 48, khoảng cách giữa các bức tường cũng vậy. Một Rect kích thước 48 pixel chỉ lọt qua khoảng trống khi được căn đúng từng pixel. Vì vậy, Rect của kỵ sĩ nhỏ hơn hình, kích thước 32 × 32, và hình được vẽ ở chính giữa Rect. Rect là phần va chạm, còn hình là thứ bạn nhìn thấy.

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

cell_rect(col, row) là Rect kích thước 32 × 32 nằm giữa một ô. Kỵ sĩ là một sprite, giống như nhân vật chạy trong Sky Runner, được tạo tại một điểm:

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
challenge icon

Thử thách

Trung bình

Đặt hiệp sĩ trong căn phòng đầu tiên, đứng trên ô P.

  1. Thêm các hàm draw và cell_rect ở phía trên.
  2. Trong Room, đặt self.start = (72, 72); ô P sẽ đặt self.start = cell_rect(col, row).center.
  3. Viết lớp Knight ở phía trên, rồi tạo knight = Knight(room.start) sau căn phòng.
  4. Sau các bức tường, gọi draw(knight.image, knight.rect).

Nhấn Chơi: hiệp sĩ đứng trên ô P. Sau đó nhấn Kiểm tra.

Tự làm thử

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

Tất cả bài học trong Dự án

Tự luyện tập: Playground Pygame