Điểm cao nhất và khởi động lại an toàn
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 30 trên 30.
Màn hình kết thúc trò chơi hiển thị điểm cao nhất và bắt đầu trò chơi mới khi nhấn phím Space. best được đặt một lần trước vòng lặp, bên ngoài reset(), nên trò chơi mới vẫn giữ giá trị này.
Trên màn hình kết thúc trò chơi, phím Space giờ đây đảm nhiệm thêm một việc thứ ba:
elif pygame.time.get_ticks() - over_time > 500:
reset()
state = "play"Space là phím nhảy, nên người chơi thường nhấn phím này ngay lúc va chạm. Nếu không chờ, trò chơi sẽ khởi động lại trước khi họ kịp thấy kết quả. Ghi nhớ thời điểm va chạm trong over_time và chỉ chấp nhận phím Space trên màn hình kết thúc trò chơi sau 500 ms.
Thử thách
KhóHiển thị điểm cao nhất và khởi động lại an toàn.
- Sau
state = "menu", đặtbest = 0vàover_time = 0. Khi va chạm, đặtbest = max(best, score)và cập nhậtover_timethành thời điểm hiện tại. - Màn hình kết thúc trò chơi hiển thị
Game over,Best: 00120vàPress Space to play again. - Ở đó, phím cách gọi
reset()để chơi lại, nhưng chỉ khi đã qua 500 ms kể từ lúc va chạm.
Nhấn Chơi rồi để nhân vật va chạm: điểm cao nhất sẽ hiện ra, và phím cách sẽ bắt đầu lại. 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)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
INK = (40, 50, 80)
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
POINT = pygame.USEREVENT + 2
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(),
]
def reset():
global runner, obstacles, speed, score
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
score = 0
pygame.time.set_timer(SPAWN, 1500)
pygame.time.set_timer(POINT, 100)
def show(text, text_font, y):
picture = text_font.render(text, True, INK)
screen.blit(picture, picture.get_rect(center=(320, y)))
reset()
state = "menu"
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()
elif state == "menu":
reset()
state = "play"
if event.type == SPAWN and state == "play":
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
if event.type == POINT and state == "play":
score += 1
if state == "play":
speed = min(14, 6 + score // 100)
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 == "menu":
show("Sky Runner", big_font, 110)
show("Press Space to start", font, 170)
else:
score_text = font.render(f"{score:05}", True, INK)
screen.blit(score_text, score_text.get_rect(topright=(630, 10)))
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()
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
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