Menu cho Người chạy trên trời
Thuộc phần Luật chơi trong hành trình Pygame của Coddy. Bài học 29 trên 30.
Sky Runner lấy luật chơi từ phần này, bắt đầu bằng một menu. Một ván mới cần đưa mọi thứ về trạng thái ban đầu, vậy nên hãy đặt phần đó vào reset(): một người chạy mới, một nhóm trống, tốc độ và điểm số, cùng cả hai bộ hẹn giờ được khởi động lại.
Giờ đây, phím cách đảm nhiệm hai việc, mỗi việc ứng với một trạng thái:
if state == "play":
runner.jump()
elif state == "menu":
reset()
state = "play"Menu cần hai dòng được căn giữa, còn màn hình kết thúc trò chơi sẽ cần ba dòng, vì vậy một hàm nhỏ sẽ vẽ một dòng căn giữa tại x 320:
def show(text, text_font, y):
picture = text_font.render(text, True, INK)
screen.blit(picture, picture.get_rect(center=(320, y)))Điểm số thuộc về một ván chơi, vì vậy chỉ hiển thị điểm sau khi ván chơi bắt đầu, không hiển thị trên menu.
Thử thách
Trung bìnhThêm menu cho Sky Runner.
- Viết
reset()cho nhân vật chạy, nhóm,speed,scorevà cả hai bộ hẹn giờ; gọi hàm này trước vòng lặp và đặtstate = "menu". - Trong menu, dùng
show()để hiển thịSky Runnerbằngbig_fontvàPress Space to start; chỉ hiển thị điểm số khi không ở trong menu. - Nhấn Space trong menu sẽ gọi
reset()và đặtstate = "play".
Nhấn Chơi: Space bắt đầu lượt chơ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)
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(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
pygame.time.set_timer(POINT, 100)
score = 0
state = "play"
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()
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)
score_text = font.render(f"{score:05}", True, (40, 50, 80))
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()
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