Rozdział 19 · Funkcje gry
Restart / New Game
Nowa gra musi przerwać stary łańcuch ticków, inaczej przez chwilę będziesz mieć dwa niezależne łańcuchy ticków jednocześnie.
Restart musi przerwać stary łańcuch kleszczy
Restart nie tylko przywraca węża na jego pierwotne miejsce — sekcja 19.22 ostrzega:
jeśli stary łańcuch ontimer() wciąż tyka, gra trwa
Za chwilę pojawiłyby się dwie niezależne serie aktualizacji jednocześnie (rozdział 16 już
Analizowałem podobny problem z ponownym naciśnięciem przycisku).
restart.py
def restart(self):
self._generation += 1 # przerywa wszelki wciąż tykający łańcuch poprzedniej gry
high_score = self.state.high_score
self.state = new_game_state(self.rng, high_score=high_score)
self._clear_overlay()
self.render()
generation_guard.py
def _schedule_next_tick(self):
generation = self._generation
self.screen.ontimer(lambda: self._on_timer(generation), self.state.delay_ms)
def _on_timer(self, generation):
if generation != self._generation:
return # wygasły łańcuch od gry do restart() – sam się gasnie
self.game_tick()
if self.state.status is GameStatus.RUNNING:
self._schedule_next_tick()
Generowanie (generation) — prosty licznik, nie skomplikowana architektura
Każdy
restart() zwiększa _generation na jednostkę. Jakieś już zaplanowane _on_timer() zapamiętał znaczenie OLD – gdy w końcu działa, liczba się nie zgadza i cicho nic nie robi, zamiast przesuwać już nieistniejącego węża z poprzedniej gry.high_score — jedyne pole, które restart przenosi ze starego stanu do nowego; wszystko pozostałe tworzone jest na nowo przez
new_game_state() (Rozdział 19.25).
Praktyka: restart i przeterminowane kleszcze
Automatyczna Weryfikacja – Funkcje new_game_state() i restart(): rekord się restartuje, generacja rośnie