Menu
CoddyTech

Hiệp sĩ

Bài học 2 trên 25 trong khóa học Dự án Pygame: Trấn giữ thành trì của Coddy.

Hiệp sĩ là một sprite: một lớp được xây dựng dựa trên pygame.sprite.Sprite, lưu hình ảnh trong self.image và vị trí trong self.rect.

class Knight(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = knight_img
        self.rect = pygame.Rect(0, 0, 24, 24)
        self.rect.center = courtyard.center

Hình ảnh có kích thước 48 pixel mỗi chiều, nhưng Rect chỉ có kích thước 24. Quái vật sẽ va chạm với Rect, vì vậy quái vật phải chạm đến thân hiệp sĩ, chứ không phải góc của khoảng trống xung quanh. Hitbox nhỏ giúp người chơi thấy công bằng hơn.

Vì hình ảnh và Rect có kích thước khác nhau, hãy vẽ hình ảnh sao cho tâm của nó nằm tại tâm của Rect. image.get_rect(center=point) tạo một Rect có kích thước bằng hình ảnh và tâm nằm tại một điểm, còn blit nhận Rect này làm vị trí để vẽ:

def draw(image, center):
    screen.blit(image, image.get_rect(center=center))
challenge icon

Thử thách

Dễ

Đặt hiệp sĩ vào giữa sân trong.

  1. Tải hình của hiệp sĩ: knight_img = load("knight.png").
  2. Viết lớp (class) Knight ở phía trên: hình knight_img, một rect có kích thước 24 nhân 24, đặt giữa tại courtyard.center.
  3. Viết hàm (function) draw(image, center).
  4. Trước vòng lặp, tạo knight = Knight(), rồi sau khi vẽ nền, vẽ hiệp sĩ bằng draw(knight.image, knight.rect.center).

Nhấn Chơi: hiệp sĩ đứng giữa sân trong. Sau đó nhấn Kiểm tra.

Tự làm thử

import pygame

WIDTH, HEIGHT = 720, 480
TILE = 48

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Hold the Keep")
clock = pygame.time.Clock()


def load(name):
    return pygame.image.load("assets/images/" + name).convert_alpha()


floor_img = load("floor.png")
wall_img = load("wall.png")

courtyard = pygame.Rect(TILE, TILE, WIDTH - 2 * TILE, HEIGHT - 2 * TILE)
background = pygame.Surface((WIDTH, HEIGHT))
for row in range(HEIGHT // TILE):
    for col in range(WIDTH // TILE):
        x = col * TILE
        y = row * TILE
        if courtyard.collidepoint(x, y):
            background.blit(floor_img, (x, y))
        else:
            background.blit(wall_img, (x, y))



running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.blit(background, (0, 0))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Dự án Pygame: Trấn giữ thành trì

Tự luyện tập: Playground Pygame