Menu
CoddyTech

Menu dan Skor Terbaik

Termasuk bagian Aturan Game dalam perjalanan Pygame di Coddy. Pelajaran 29 dari 29.

Sky Runner mendapatkan aturan dari bagian ini: menu, permainan baru dengan tombol, dan skor terbaik.

reset() membuat runner baru dan grup kosong, mengatur ulang skor dan kecepatan, lalu memulai ulang kedua timer. Permainan dimulai dalam keadaan "menu", dan best diatur satu kali, di luar reset().

Sekarang tombol Spasi memiliki tiga fungsi, satu untuk setiap keadaan:

if state == "play":
    runner.jump()
elif state == "menu":
    reset()
    state = "play"
elif pygame.time.get_ticks() - over_time > 500:
    reset()
    state = "play"

Tombol Spasi digunakan untuk melompat, jadi pemain sering kali sedang menekannya saat mengalami tabrakan. Tanpa jeda, permainan akan dimulai ulang sebelum pemain sempat melihat hasilnya. Catat waktu tabrakan di over_time dan terima tombol Spasi di layar game over hanya 500 ms kemudian.

Fungsi kecil show(text, text_font, y) menggambar baris yang dipusatkan pada x 320, karena menu dan layar game over memerlukan lima baris.

challenge icon

Tantangan

Sulit
  1. Tulis reset() untuk runner, group, speed, score, dan kedua timer. Panggil fungsi ini sebelum perulangan, lalu atur state = "menu", best = 0, dan over_time = 0.
  2. Di menu, tampilkan Sky Runner (ukuran 48) dan Press Space to start. Tombol Space atau Up memulai permainan.
  3. Saat terjadi tabrakan, perbarui best dan atur over_time.
  4. Di layar game over, tampilkan Game over, Best: 00120 (lima digit), dan Press Space to play again. Tombol Space memulai permainan baru, tetapi hanya setelah 500 ms sejak tabrakan.
  5. Tampilkan skor hanya selama permainan berlangsung dan di layar game over.

Coba sendiri

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()
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Aturan Game

Latihan sendiri: Playground Pygame