#Piszemy gre w SFML’u – Lekcja 3, część 2

Druga część 3 lekcji, tutaj dowiesz się jak napisać kolizję używającą bounding box’ów

!UWAGA! Kurs leży w kategorii ‚Obsolete’ co oznacza, że może być nieaktualny, zawierać błędy i nie polecam z niego korzystać. [INFO]

Kod z poprzedniej lekcji

Podczas tej lekcji napiszemy system kolizji pomiędzy graczem, a otoczeniem, jednak zanim przejdziemy dalej chciałbym przedstawić dokładniej sposób wykrywania kolizji przedstawiony w tej lekcji.

Generalnie w świecie 2D istnieje kilka sposobów wykrywania kolizji:

  • bounding box (box collider) metoda, którą zajmiemy się dzisiaj. Polega ona na „nałożenie” czworokąta na jakiś obiekt i sprawdzeniu czy box innego obiektu nie przecina naszego obiektu. Ten sposób ma taką wadę, że jest mało dokładny (możemy go zobaczyć na obrazku powyżej).
  • circle collider – analogiczna do box collider, tyle że zamiast czworokąta używa się okręgu, zwykle używa się go w połączeniu z box collider
  • polygon collider – zdecydowanie najdokładniejszy sposób wykrywania kolizji, ale jednocześnie najtrudniejszy w implementacji, skorzystamy z niego w kolejnych lekcjach tego poradnika

SFML posiada gotowe narzędzia do tworzenia bounding box’ów, między innymi do wykrywania kolizji pomiędzy dwoma czworokątami metodę intersects.

Zacznijmy od napisania kilku nowych metod w klasie Player.

Napisaliśmy sobie kilka metod pomocniczych: do pobrania pozycji (trzeba pamiętać, że to pozycja środka gracza), statusu (aby wiedzieć czy się poruszamy), bounding box’a (do wykrywania kolizji) oraz do pobrania prędkości.

Przejdźmy do klasy Engine, gdzie utworzymy sobie metodę check_collision().

Teraz zaczyna się ciekawa rzecz, w zasadzie moglibyśmy utworzyć sobie podwójną pętlę o wymiarach poziomu i sprawdzać dla każdego kafla czy wykryto kolizję, ale jest to mało efektywne.

Pierwszym krokiem wykrycia kolizji jest oczywiście pobrania box’a oraz zaktualizowanie go do takiej wartości gdyby gracz się poruszył.

Następnie sprawdzamy 4 wierzchołki naszej figury, numer kafelka (dotyczy tablic dwuwymiarowych) o danej współrzędnej można policzyć w ten sposób: = pozycja (x lub y) / szerokość_kafla i co ważne zmienna musi być typu int aby pozbyć się liczb po przecinku.

Kolejne współrzędne wierzchołków otrzymywałem poprzez dodawanie szerokości/wysokości kafla do pozycji lewego górnego rogu. Oto wszystkie warunki:

Ostatnim krokiem jest zmiana metody Player::idz() poprzez przeniesienie z niej sprite.move(…) do update.

Chciałbym Was także ostrzec, że ta metoda w obecnym przykładzie, czyli widoku z góry na postać, która dodatkowo się obraca jest mało efektywna, a to dlatego, że postać właśnie się obraca i nakładany na nią box nie zawsze jest tej samej wielkości, czasami jest szerszy, czasami węższy zależnie od rotacji, co nie wpływa dobrze na wykrywanie kolizji, dużo lepszym sposobem do wykrywania kolizji byłby circle collider. Ewentualnie można dodać do obecnego sposobu kilka warunków aby nie zawsze sprawdzać kolizję dla wszystkich rogów.

Zmiana rozmiaru box collidera

Kod źródłowy:
>>Pobierz<< | >>GitHub<<