Menu
CoddyTech

Her Durum için Bir Fonksiyon

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

Döngü üç ekranı bir arada yönetiyordu ve her yeni durum, çizim ve güncelleme kodunun içine bir katman daha if ekleyecekti. Başlangıç kodunda bunun yerine her durumun kendi işlevi var ve döngü bunlardan birini seçiyor:

if state == "menu":
    draw_menu()
elif state == "play":
    play_frame()
else:
    draw_over()

play_frame() nesneleri hareket ettirir, çarpışmayı kontrol eder ve çizer. draw_menu() ve draw_over() yalnızca çizer. Oyun bitti ekranında, mesajın altında donmuş oyun görünür; bu yüzden her ikisi de oyuncuyu, kayayı ve skoru çizmek için ortak bir draw_game() kullanır.

Durumu veya skoru değiştiren bir işlevin bunları global'dan sonra belirtmesi gerekir:

def play_frame():
    global score, state

player.x'i değiştirmek için global gerekmez: yeni bir Rect atamak yerine Rect'in kendisini değiştirir.

Bu yapıda yeni bir durum, tek bir işlev ve tek bir elif demektir. Bu şekilde bir duraklatma ekranı ekle.

challenge icon

Görev

Orta
  1. Bir "paused" durumu ekle: Oyun sırasında P'ye basınca duraklatılır, P'ye tekrar basınca oyuna dönülür.
  2. draw_paused() işlevini yaz: donmuş oyun ve (240, 160) konumunda ortalanmış Paused.
  3. Durum "paused" iken döngüden, bir elif daha ekleyerek çağır.

Kendin dene

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()
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