Điểm số cao nhất
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 19 trên 30.
Điểm số có ý nghĩa hơn khi đặt cạnh điểm cao nhất từ trước đến nay. Lưu điểm cao nhất trong biến riêng và cập nhật ngay khi trò chơi kết thúc:
if lives <= 0:
state = "over"
best = max(best, score)max giữ lại số lớn hơn. Trò chơi có kết quả tốt hơn sẽ nâng best; kết quả kém hơn thì giữ nguyên giá trị.
Vị trí bạn đặt best = 0 rất quan trọng. reset() chạy khi bắt đầu mỗi trò chơi, vì vậy nếu đặt giá trị cao nhất ở đó, mỗi lần nhấn R, giá trị sẽ bị xóa. Hãy đặt giá trị này một lần trước vòng lặp. Nó tồn tại chừng nào chương trình còn chạy.
Hiển thị giá trị này trên màn hình kết thúc trò chơi, bên dưới hai dòng còn lại:
best_text = font.render(f"Best: {best}", True, WHITE)
screen.blit(best_text, best_text.get_rect(center=(240, 240)))Thử thách
DễGiữ điểm cao nhất của phiên chơi.
- Đặt
best = 0một lần, saustate = "menu". - Khi trò chơi kết thúc, đặt
best = max(best, score). - Trên màn hình kết thúc trò chơi, hiển thị
Best: 12(cùng với điểm cao nhất) ở giữa tại (240, 240).
Nhấn Chơi rồi để thua: màn hình kết thúc trò chơi hiển thị điểm cao nhất của bạn. Sau đó nhấn Kiểm tra.
Tự làm thử
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2
def reset():
global player, rocks, score, lives
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 800)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
pygame.draw.rect(screen, (255, 196, 0), player)
for rock in rocks:
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global rocks, lives, state
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
kept = []
for rock in rocks:
rock.y += 3
if rock.colliderect(player):
lives -= 1
elif rock.top <= 360:
kept.append(rock)
rocks = kept
if lives <= 0:
state = "over"
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
reset()
state = "menu"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == SPAWN and state == "play":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
reset()
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
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