Menu
CoddyTech

Menü ve En İyi Skor

Coddy'nin Pygame Journey'sinin Oyun Kuralları bölümünün bir parçası. Ders 29 / 29.

Sky Runner kuralları bu bölümden alır: bir menü, bir tuşla yeni oyun ve en iyi skor.

reset() yeni bir koşucu ve boş bir grup oluşturur, skoru ve hızı sıfırlar ve her iki zamanlayıcıyı yeniden başlatır. Oyun "menu" durumunda başlar ve best, reset() dışında bir kez ayarlanır.

Artık Space, her durum için bir tane olmak üzere üç iş yapar:

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

Space zıplama tuşudur; bu yüzden oyuncu genellikle kaza anında bu tuşa basıyor olur. Bekleme olmazsa oyuncu sonucu görmeden oyun yeniden başlardı. Kazanın gerçekleştiği zamanı over_time içinde kaydedin ve oyun bitti ekranında Space tuşuna ancak 500 ms sonra basılmasını kabul edin.

Küçük bir show(text, text_font, y) işlevi, menü ve oyun bitti ekranı beş satıra ihtiyaç duyduğundan, x 320'de ortalanmış bir satır çizer.

challenge icon

Görev

Zor
  1. Oyuncu, grup, speed, score ve her iki zamanlayıcı için reset() yaz; döngüden önce çağır ve state = "menu", best = 0 ve over_time = 0 değerlerini ayarla.
  2. Menüde Sky Runner (boyut 48) ve Press Space to start metinlerini göster; Space veya Up bir oyunu başlatır.
  3. Çarpışma olduğunda best değerini güncelle ve over_time değerini ayarla.
  4. Oyun bitti ekranında Game over, Best: 00120 (beş basamaklı) ve Press Space to play again metinlerini göster; Space yeni bir oyun başlatır, ancak çarpışmadan yalnızca 500 ms sonra.
  5. Skoru yalnızca oyun sırasında ve oyun bitti ekranında göster.

Kendin dene

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 iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Oyun Kuralları bölümündeki tüm dersler

Kendi başına pratik yap: Pygame playground