Mỗi trạng thái một hàm
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 5 trên 30.
Vòng lặp kết hợp ba màn hình, và mỗi trạng thái mới lại thêm một lớp if bên trong phần vẽ và cập nhật. Đoạn code khởi đầu đặt mỗi trạng thái vào một hàm riêng, còn vòng lặp chọn một hàm:
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()play_frame() di chuyển các vật thể, kiểm tra va chạm và vẽ. draw_menu() và draw_over() chỉ vẽ. Màn hình kết thúc trò chơi hiển thị trò chơi đã dừng bên dưới thông báo, nên cả hai đều dùng chung draw_game() để vẽ người chơi, tảng đá và điểm số.
Hàm thay đổi trạng thái hoặc điểm số cần khai báo chúng sau global:
def play_frame():
global score, stateDi chuyển player.x không cần global: thao tác này thay đổi Rect, chứ không gán một Rect mới.
Với cấu trúc này, trạng thái mới chỉ cần một hàm và một elif. Hãy thêm màn hình tạm dừng theo cách đó.
Thử thách
Trung bìnhThêm chức năng tạm dừng vào trò chơi.
- Thêm trạng thái
"paused": nhấn P khi đang chơi để tạm dừng, nhấn P lần nữa để tiếp tục chơi. - Viết
draw_paused(): hiển thị trò chơi đang tạm dừng vớiPausedở giữa tại (240, 160). - Gọi hàm này trong vòng lặp khi trạng thái là
"paused", bằng cách thêm mộtelif.
Nhấn Chơi rồi nhấn P trong lúc chơi: trò chơi sẽ đóng băng và hiển thị Paused. 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()
font = pygame.font.Font(None, 32)
WHITE = (240, 240, 240)
def reset():
global player, rock, score
player = pygame.Rect(220, 300, 40, 40)
rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
score = 0
def draw_menu():
screen.fill((30, 30, 46))
title = font.render("Meteor Dodge", True, WHITE)
screen.blit(title, title.get_rect(center=(240, 140)))
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)
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
def play_frame():
global score, 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())
rock.y += 4
if rock.top > 360:
rock.y = -24
rock.x = random.randint(0, 456)
score += 1
if rock.colliderect(player):
state = "over"
draw_game()
def draw_over():
draw_game()
message = 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 == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
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
1Trạng thái trò chơi
Một biến trạng tháiMàn hình menuNhấn R để chơi lạiMột hàm đặt lạiMỗi trạng thái một hàmTự luyện tập: Playground Pygame