Đ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.
Thử thách
Trung bìnhTính điểm theo quãng đường và tăng tốc trò chơi.
- Thêm
POINT = pygame.USEREVENT + 2, bộ hẹn giờ chạy mỗi 100 ms vàscore = 0. - Khi đang chơi và có
POINT, cộng 1 vào điểm. - Khi đang chơi, đặt
speed = min(14, 6 + score // 100)trước khi cập nhật. - 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
3Bộ hẹn giờ và các đợt
An toàn sau khi trúng đònSự kiện hẹn giờMột tảng đá sau mỗi 800 msCác đợt ngày càng lớnĐếm ngược đến lúc bắt đầu6Người chạy trên trời
Người chạyNhảyTự luyện tập: Playground Pygame