Menu
CoddyTech

Đêm

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

Trò chơi sắp có nhiều thứ: hiệp sĩ, quái vật, tia đạn, đá quý và thời gian. Gom tất cả vào một đối tượng, night, được tạo từ lớp Night. Sau này, bạn chỉ cần một dòng để bắt đầu lại: night = Night().

class Night:
    def __init__(self):
        self.knight = Knight()
        self.time = 0

    def update(self, keys):
        self.time += 1
        self.knight.move(keys)

update chạy một khung hình của đêm. Với tốc độ 60 khung hình mỗi giây, một đêm kéo dài bốn phút sẽ có NIGHT = 60 * 60 * 4 khung hình.

Để hiển thị thời gian còn lại, chuyển số khung hình thành phút và giây bằng // (phép chia lấy phần nguyên) và % (phần dư):

def clock_text(frames):
    seconds = frames // 60
    return f"{seconds // 60}:{seconds % 60:02d}"

:02d viết số có ít nhất hai chữ số, nên 65 giây sẽ hiển thị là 1:05, không phải 1:5.

challenge icon

Thử thách

Dễ

Đếm ngược một đêm kéo dài bốn phút.

  1. Thêm NIGHT = 60 * 60 * 4, WHITE = (240, 240, 240) và font = pygame.font.Font("assets/fonts/pixel.ttf", 24).
  2. Viết lớp Night ở phía trên và clock_text(frames).
  3. Thay knight = Knight() bằng night = Night(). Trong vòng lặp, gọi night.update(pygame.key.get_pressed()) và vẽ night.knight.
  4. Vẽ thời gian còn lại bằng màu trắng, căn giữa tại (360, 24): clock_text(max(0, NIGHT - night.time)) + " until dawn".

Nhấn Chơi: thanh trên cùng đếm ngược từ 4:00 đến khi trời sáng. 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")
knight_img = load("knight.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))


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


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
        self.speed = 3

    def move(self, keys):
        if keys[pygame.K_LEFT]:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT]:
            self.rect.x += self.speed
        if keys[pygame.K_UP]:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN]:
            self.rect.y += self.speed
        self.rect.clamp_ip(courtyard)


knight = Knight()

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

    knight.move(pygame.key.get_pressed())

    screen.blit(background, (0, 0))
    draw(knight.image, knight.rect.center)
    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