Menu
CoddyTech

Điểm số và tốc độ

Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 28 trên 30.

Một trò chơi chạy vô tận tính điểm theo quãng đường. Cứ mỗi 100 ms, bộ hẹn giờ cộng một điểm, nên chạy trong một giây được 10 điểm:

POINT = pygame.USEREVENT + 2
pygame.time.set_timer(POINT, 100)

Hiển thị điểm ở góc trên bên phải với các số 0 ở đầu, 00042, như trong Meteor Dodge.

Trò chơi sẽ khó hơn khi bạn tiến xa hơn. Gắn tốc độ với điểm số: 6 pixel mỗi khung hình lúc bắt đầu, tăng thêm một sau mỗi 100 điểm, nhưng không bao giờ vượt quá 14:

speed = min(14, 6 + score // 100)

Obstacle.update() đọc speed mỗi khung hình, nên tốc độ mới cũng áp dụng cho các chướng ngại vật đã xuất hiện trên màn hình. min đặt giới hạn trên: ở tốc độ 14, chướng ngại vật băng qua cửa sổ trong chưa đầy một giây, nếu nhanh hơn thì người chơi không thể phản ứng kịp.

challenge icon

Thử thách

Trung bình

Tính điểm theo quãng đường và tăng tốc trò chơi.

  1. Thêm POINT = pygame.USEREVENT + 2, bộ hẹn giờ chạy mỗi 100 ms và score = 0.
  2. Khi đang chơi và có POINT, cộng 1 vào điểm.
  3. Khi đang chơi, đặt speed = min(14, 6 + score // 100) trước khi cập nhật.
  4. Hiển thị điểm bằng năm chữ số với màu (40, 50, 80) và topright=(630, 10).

Nhấn Chơi: điểm sẽ tăng dần. Sau đó nhấn Kiểm tra.

Tự làm thử

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)

SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1


class Runner(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.frames = [
            pygame.image.load("assets/images/player.png").convert_alpha(),
            pygame.image.load("assets/images/player_walk.png").convert_alpha(),
        ]
        self.image = self.frames[0]
        self.step = 0
        self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
        self.vy = 0

    def jump(self):
        if self.rect.bottom == GROUND_Y:
            self.vy = -16

    def update(self):
        self.vy += GRAVITY
        self.rect.y += self.vy
        if self.rect.bottom >= GROUND_Y:
            self.rect.bottom = GROUND_Y
            self.vy = 0
        if self.rect.bottom == GROUND_Y:
            self.step += 1
            self.image = self.frames[self.step // 8 % 2]
        else:
            self.image = self.frames[1]


class Obstacle(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = random.choice(obstacle_images)
        self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))

    def update(self):
        self.rect.x -= speed
        if self.rect.right < 0:
            self.kill()


obstacle_images = [
    pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
    pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
state = "play"

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
            if state == "play":
                runner.jump()
        if event.type == SPAWN and state == "play":
            obstacles.add(Obstacle())
            pygame.time.set_timer(SPAWN, random.randint(1000, 2000))

    if state == "play":
        runner.update()
        obstacles.update()
        if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
            state = "over"

    screen.fill(SKY)
    pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
    screen.blit(runner.image, runner.rect)
    obstacles.draw(screen)
    if state == "over":
        message = font.render("Game over", True, (40, 50, 80))
        screen.blit(message, message.get_rect(center=(320, 140)))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Luật chơi

Tự luyện tập: Playground Pygame