Silnik gier: timery ze skryptu (za chwilę, co chwilę)
Silnik gier 2D Moonlight Studio dostał timery sterowane wprost ze skryptu: „zrób coś za 3 sekundy" i „rób coś co pół sekundy" — bez zakładania żadnego węzła w scenie. To budulec połowy logiki gry: respawn po śmierci, cooldown umiejętności, fala wrogów co kilka sekund, odliczanie do startu.
Dwie funkcje
mp.after(3.0, function() mp.spawn("wróg") end) -- raz, za 3 sekundy
local tick = mp.every(0.5, function() punkty = punkty + 1 end) -- co 0,5 s
mp.after odpala callback jeden raz; mp.every powtarza go w równych odstępach. Oba zwracają uchwyt, którym można je odwołać:
mp.cancel_timer(tick)
Czas gry, nie czas rzeczywisty
Timery liczą czas gry: pauza je zamraża (wznawiasz — dokańczają), a spowolnienie czasu (slow-motion) spowalnia je tak samo jak resztę świata. Dzięki temu „za 3 sekundy" znaczy trzy sekundy rozgrywki, a nie trzy sekundy zegara — nawet gdy gracz otworzy menu.
Zaprojektowane, by się nie wywrócić
Timer odpala Twój kod, a Twój kod może robić wszystko — w tym zakładać kolejne timery albo anulować sam siebie w trakcie odpalania. To klasyczne miejsce na trudne błędy; tutaj jest bezpieczne z założenia:
- callback może w środku założyć nowe timery — nic się nie psuje,
- callback może anulować sam siebie — po prostu przestaje się powtarzać,
- powtarzalny timer po długiej zadyszce (np. gra na chwilę zamarła) nie zaleje Cię setką zaległych wywołań — nadrabianie jest ograniczone,
- kolejność jest deterministyczna: dwa timery kończące się w tej samej klatce odpalą w kolejności założenia.
Dwa oblicza tej samej idei
W edytorze scen jest osobny, „nastawiany" węzeł czasomierza — do timerów projektowanych wizualnie. mp.after/mp.every to jego imperatywny odpowiednik dla logiki pisanej w kodzie. Oba dzielą ten sam rdzeń odliczania — jedna idea, dwa sposoby użycia, zero powielania.
Co dalej
W kolejce: timery dostępne również z wizualnego grafu zdarzeń oraz opcja „licz mimo pauzy" dla odliczań w menu.