Lưu kỷ lục
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 20 trên 30.
Đóng trò chơi là best biến mất: các biến chỉ tồn tại khi chương trình đang chạy. Để giữ lại một con số cho lần sau, hãy ghi số đó vào một tệp.
with open("highscore.txt", "w") as file:
file.write(str(best))open(..., "w") mở tệp để ghi. Lệnh này tạo tệp nếu chưa có và xóa hết nội dung nếu tệp đã tồn tại, nên tệp luôn chứa một con số. write nhận văn bản, vì vậy str(best) chuyển số thành văn bản trước. Khối lệnh with đóng tệp khi kết thúc, nhờ đó mọi nội dung đã ghi đều được lưu.
Tên tệp không có thư mục, nên tệp được tạo trong thư mục mà chương trình chạy. Trên máy tính, hãy chạy main.py từ thư mục chứa tệp đó. highscore.txt sẽ xuất hiện bên cạnh và vẫn ở đó.
Trong trình duyệt, các tệp của trò chơi nằm trong bộ nhớ của trang: chơi lại thì tệp vẫn còn, nhưng tải lại trang sẽ bắt đầu khi chưa có tệp.
Thử thách
Trung bìnhLưu điểm cao nhất vào một tệp để điểm số vẫn còn sau khi trò chơi kết thúc.
- Khi trò chơi kết thúc, sau khi cập nhật
best, hãy mởhighscore.txtvới"w"trong khốiwith. - Ghi
str(best)vào tệp.
Nhấn Chơi rồi để thua: điểm cao nhất sẽ được lưu trong highscore.txt. 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, best
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"
best = max(best, score)
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)))
best_text = font.render(f"Best: {best}", True, WHITE)
screen.blit(best_text, best_text.get_rect(center=(240, 240)))
reset()
state = "menu"
best = 0
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