13.07.2026 16:53

Silnik gier 2D: pytanie „co jest TERAZ w tym miejscu?” — zapytania obszarowe

⏱️ 4 min czytania
Udostępnij:

Silnik gier w Moonlight Animate umiał już dwie rzeczy z fizyki na żądanie: rzucić promień (raycast — „co jest na tej linii?", np. linia wzroku wroga) oraz utrzymywać trwałą strefę (Area2D — „kto właśnie wszedł/wyszedł z pola?"). Brakowało trzeciego, bardzo podstawowego pytania: „jakie obiekty znajdują się TERAZ w tym prostokącie albo okręgu?" — bez zakładania na stałe żadnej strefy, w dowolnym miejscu, jednym wywołaniem. Ten klocek właśnie dołożyliśmy.

Dwie funkcje, jedno pytanie

-- Obrażenia obszarowe (AoE): rań wszystko w promieniu 128 px wokół wybuchu
for _, cel in ipairs(mp.query_circle(wybuch_x, wybuch_y, 128)) do
    zadaj_obrazenia(cel, 25)
end

-- Czy miejsce spawnu jest wolne? (prostokąt 64×64 wokół punktu)
if #mp.query_box(spawn_x, spawn_y, 64, 64) == 0 then
    stworz_przeciwnika(spawn_x, spawn_y)
end
  • mp.query_box(x, y, szerokość, wysokość [, maska]) — zwraca listę wszystkich brył, które w tej chwili nakładają się na prostokąt o środku x,y i podanych pełnych wymiarach.
  • mp.query_circle(x, y, promień [, maska]) — to samo dla okręgu.

Odpowiedź jest natychmiastowa i nie wymaga tworzenia żadnego węzła w scenie. To dopełnia komplet: promień pyta o linię, strefa Area2D o trwałe pole z historią wejść/wyjść, a nowe zapytania o dowolny obszar w danej chwili.

Dokładność, nie zgrubne pudło

Najłatwiejszy sposób na takie zapytanie to sprawdzić, czy prostokąty otaczające obiekty zahaczają o zapytany obszar. Szybkie — ale niedokładne: obiekt leżący tuż za rogiem okręgu (wewnątrz kwadratu opisanego na kole, lecz poza samym kołem) zostałby błędnie zaliczony jako trafiony. W grze to realny błąd: cios „zza węgła", spawn uznany za zajęty przez sąsiada, który wcale nie stoi na drodze.

Dlatego zapytania robią dokładny test kształtu. Dla query_circle liczy się prawdziwa odległość od środka, nie kwadrat. Obiekt z rogu okręgu nie trafia na listę — dokładnie tak, jak gracz się tego spodziewa.

Detale, które robią różnicę

  • Bez powtórzeń. Obiekt zbudowany z kilku koliderów (np. postać z osobnym kolizerem tułowia i głowy) pojawia się na liście raz, nie tyle razy, ile ma kształtów.
  • Deterministyczna kolejność. Wynik jest zawsze uporządkowany tak samo między uruchomieniami — ważne dla powtarzalności rozgrywki, testów i systemów replay.
  • Tylko bryły fizyczne. Strefy-wyzwalacze (sensory) są pomijane — pytasz o solidne obiekty, nie o niewidzialne pola triggerów, które mają własny mechanizm (mp.bodies_in_area).
  • Warstwy kolizji. Opcjonalna maska zawęża zapytanie do wybranych warstw — pocisk gracza może pytać tylko o warstwę wrogów, ignorując samego gracza i dekoracje.
  • Odporność na śmieciowe wejście. Ujemny promień jest przycinany do zera zamiast po cichu gubić trafienia; promień zerowy działa jak precyzyjne zapytanie punktowe („co jest dokładnie tutaj?").

Zapytania działają tak samo w skryptach Lua uruchamianych na desktopie i — po kompilacji do przeglądarki — w wersji web, bo cały silnik rozgrywki to jeden wspólny kod bez zależności od platformy.

Gdzie się przydają

Obrażenia obszarowe zaklęć i wybuchów, sprawdzanie czy jest miejsce na postawienie jednostki/wieży, zaznaczanie oddziałów prostokątem w grach strategicznych, wykrywanie „czy gracz stoi na przełączniku", zbieranie przedmiotów w zasięgu — wszędzie tam, gdzie logika pyta o obszar, a nie o pojedynczy punkt czy stałą strefę. Kolejny mały, ale fundamentalny klocek dokładany do silnika gier 2D w Moonlight Animate.

📚 Powiązane posty

14.07.2026 22:19

Silnik gier: od szablonu do grywalnej gry RPG top-down

Startowy szablon silnika gier to teraz kompletny, grywalny wycinek gry RPG top-down: chodzenie po siatce, rozmowy z postaciami, przeciwnik goniący gdy...
Czytaj dalej →
14.07.2026 19:16

Moonlight Animate — system dialogów w grach

Silnik gier 2D w Moonlight Animate ma teraz kompletny system dialogów: kwestie z efektem maszyny do pisania, wybory z warunkami, zmienne fabularne i g...
Czytaj dalej →
14.07.2026 18:40

Moonlight Animate: ruchoma panorama dźwięku także w wyeksportowanym wideo

Dźwięk przejeżdżający z lewego do prawego głośnika brzmiał dobrze w podglądzie, ale eksport przez serwer zamrażał go w miejscu. Ostatnia luka parytetu...
Czytaj dalej →

📧 Bądź na bieżąco!

Zapisz się na listę oczekujących, aby otrzymywać powiadomienia o nowych postach na Dev Blog oraz informacje o starcie platformy Moonlight.