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.
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.
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.
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.