Rozdział 20 · Tworzenie gier z Pygame

Struktura Małych Gier: Klasa Game

Trzy fazy cyklu gry stają się trzema metodami tej samej klasy — tymi samymi ramami co ostateczny szkic tego rozdziału i następnego.

Do tej pory cały kod żył w zmiennych globalnych i jednej płaskiej pętli — normalnie dla edukacyjnego mini-projektu, ale niewygodne, gdy gra zaczyna mieć stany (rozdział 20.25), kilka obiektów i jakąkolwiek pauzę. Zbierzemy wszystko, czego nauczyłeś się w tym rozdziale, w jedną klasę — ten sam szkielet architektoniczny, na którym oparty jest finalny projekt rozdziału 20.33 i kosmicznego strzelanka rozdziału 21.

Gamescreenclockstaterunninghandle_events()update(dt)render()run()
Każda metoda odpowiada za dokładnie jedną fazę pętli gry w sekcji 20.14 i nie więcej.

To szkic szkieletu, a nie pełny plik: pomija import pygame , definicja SHIRINA/VYSOTA, Klasa SostoyanieIgry z sekcji 20.25 i Treści Metody toggle_pause() — wszystko to w prawdziwym projekcie, oczywiście, powinno być zdefiniowany. Kompletnym, naprawdę możliwym do uruchomienia przykładem takiej klasy jest projekt końcowy Rozdział 20.33.

fragment_class_game.py
class Game:
    def __init__(self):
        pygame.init()
        self.screen = pygame.display.set_mode((SHIRINA, VYSOTA))
        self.clock = pygame.time.Clock()
        self.state = SostoyanieIgry.MENU
        self.running = True

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_p:
                self.toggle_pause()

    def update(self, dt):
        if self.state is not SostoyanieIgry.IGRA:
            return   # zatrzymaj się albo nie ruszaj niczego w menu
        # tutaj – aktualizacja pozycji, kolizji, wynik

    def render(self):
        self.screen.fill((20, 20, 40))
        # tutaj jest renderowanie wszystkich obiektów w aktualnym stanie
        pygame.display.flip()

    def run(self):
        while self.running:
            dt = self.clock.tick(60) / 1000
            self.handle_events()
            self.update(dt)
            self.render()
        pygame.quit()

run() — jedyne miejsce, gdzie widać cały cykl w całości, i powtarza dosłownie trzy fazy z rozdziału 20.14: handle_events() to Input, update(dt) tego Update, render() to Render. Tak właśnie kończy się bouncing_ball.py (rozdział 20.33) — i w tym samym stylu w rozdziale 21 napisano kosmiczny shooter.

Pauza nie zatrzymuje sterowania
Jeśli czek self.state is not SostoyanieIgry.IGRA włożone tylko render(), nie w update()ekran wizualnie zawiesza się poprawnie podczas pauzy — ale obiekty będą się dalej poruszać w pamięci, a po usunięciu pauzy gra „teleportuje się” update(), nie tylko w renderingu.
Praktyka: Składanie klasy Game
Pygame otwiera natywne okno Python – uruchomione lokalnie w VS Code, PyCharm lub Jupyter
Praktyka kursuje lokalnie
Otwórz praktykę →