Bình thường hay khó
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 17 trên 30.
Cho người chơi chọn độ khó của trò chơi trước khi bắt đầu. Menu hiển thị hai tùy chọn, và các phím mũi tên chọn một tùy chọn:
elif event.key == pygame.K_LEFT and state == "menu":
difficulty = "normal"
elif event.key == pygame.K_RIGHT and state == "menu":
difficulty = "hard"Các phím mũi tên cũng di chuyển người chơi trong lúc chơi. Kiểm tra state == "menu" giúp tách biệt hai cách sử dụng.
Menu đánh dấu tùy chọn đã chọn để người chơi biết phím Enter sẽ bắt đầu chế độ nào:
if difficulty == "normal":
normal, hard = "> Normal <", "Hard"
else:
normal, hard = "Normal", "> Hard <"Sau đó, trò chơi đọc difficulty tại nơi thiết lập các con số. Ở chế độ Hard, đá bắt đầu di chuyển với tốc độ 6 pixel mỗi khung hình thay vì 3:
if difficulty == "normal":
speed = 3 + seconds // 5
else:
speed = 6 + seconds // 5Đặt difficulty = "normal" một lần trước vòng lặp, không đặt trong reset(), để phím R giữ nguyên lựa chọn.
Thử thách
Trung bìnhĐể người chơi chọn Normal hoặc Hard.
- Đặt
difficulty = "normal"trước vòng lặp; trên menu, phím Left đặt thành"normal", phím Right đặt thành"hard". - Căn giữa các tùy chọn tại (160, 260) và (320, 260):
> Normal <vàHard, hoặcNormalvà> Hard <. - Đá bắt đầu rơi với tốc độ 3 pixel mỗi khung hình ở chế độ Normal, 6 ở chế độ Hard, cộng thêm 1 sau mỗi năm giây.
Nhấn Chơi rồi nhấn Right: Hard được đánh dấu. 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, start_time
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
start_time = pygame.time.get_ticks()
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 1000)
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())
seconds = (pygame.time.get_ticks() - start_time) // 1000
speed = 3 + seconds // 5
kept = []
for rock in rocks:
rock.y += speed
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))
seconds = (pygame.time.get_ticks() - start_time) // 1000
interval = max(400, 1000 - seconds * 60)
pygame.time.set_timer(SPAWN, interval)
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