Rozdział 21 · Projekt: kosmiczny strzelec

Szybkostrzelność i odstępy między strzałami

Przytrzymanie spacji strzela z ograniczoną częstotliwością — w sekundach, a nie w klatkach.

Rozdział 21.4 Zwolniona podczas zdarzenia KEYDOWN – to się dzieje dokładnie raz na jedno fizyczne naciśnięcie spacji, więc nawet trzymanie klawisza przez dłuższy czas dawało Tylko jeden strzał. Ostateczna wersja gry wymaga serii strzałów podczas zaciskania spacji, a dla wymaga innego źródła danych — pygame.key.get_pressed(), Który informuje, czy klawisz jest teraz przytrzymywany przy każdej aktualizacji. Nieograniczone oznaczałoby to strzał przy każdej aktualizacji gry, czyli szybkostrzelność opartą na FPS: 60 strzały na sekundę przy 60 FPS i 120 przy 120 FPS. Dlatego strzelanie przez get_pressed() zawsze towarzyszy minimalny odstęp między strzały (cooldown, w profesjonalnej mowie – czas odnowienia), oddawane w sekundy.

fragment_fire_cooldown.py
FIRE_INTERVAL = 0.20   # sekund między strzałami

self.fire_cooldown = max(0.0, self.fire_cooldown - dt)

if keys[pygame.K_SPACE] and self.fire_cooldown <= 0.0:
    self._spawn_bullet()
    self.fire_cooldown = FIRE_INTERVAL
Interwał mierzony jest w sekundach, a nie w klatkach
Gdyby zamiast fire_cooldown -= dt licznik zmniejszany o jeden w każdej klatce (kadrov_do_vystrela -= 1), prędkość strzału zależałaby od FPS dokładnie tak samo, jak nieskorygowany ruch z sekcji 20.16: przy 120 FPS statek strzelałby dwa razy częściej niż przy 60 FPS, przy tym samym kodzie.

Dlaczego tutaj nie używa się while, jak w timerze pojawiania się wrogów

Rozdział 21.14 pokaże ostatni licznik pojawiania się wrogów: przesuwa czas do przodu += interval, zachowując resztę, oraz while jest tam potrzebne, jeśli jeden przetworzony etap pokryje kilka przedziałów jednocześnie. Interwały między strzałami są ułożone inaczej:

Timer pojawiania się wrogówInterwał między strzałami zawodników
Źródło zdarzeniaSymulacja offline (sama gra decyduje, kiedy nastąpi)Wprowadzanie gracza (człowiek decyduje, kiedy)
Długi etap przetwarzaniaJeśli krok może obejmować wiele interwałów, timer może przetwarzać wiele zdarzeń z rzędunie wolno wystrzeliwać kilku pocisków jednocześnie w jednej klatce
Trik w kodziewhile: kontynuować, dopóki jest czasif: nie więcej niż jedno ujęcie na klatkę
W bieżącej grze drugi wiersz nie następuje
MAX_DT nie pozwala, aby pojedynczy przetworzony krok był dłuższy od minimalnego interwału pojawiania się wrogów (szczegóły — w rozdziale 21.14) — dlatego w tej konkretnej grze ani przerwa debuggera, ani zawieszenie systemu nie powodują, że gra „nadgania” cały nagromadzony czas rzeczywisty naraz od kilku wrogów.
To świadomy wybór, a nie przeoczenie
Po naprawdę długim strzale (pauza debugera, zamrożenie systemu) nagła salwa dziesięciu pocisków wydaje się raczej błędem niż uczciwym zachowaniem — więc interwał strzału celowo daje maksymalnie jeden nowy strzał na odświeżenie, nawet jeśli dt okazała się duża.
Praktyka: Przerwa między ujęciami
Zeskanowanie bezpośrednio w przeglądarce – nie wymaga instalacji Pygame
Praktyka kursuje lokalnie
Otwórz praktykę →