Lekcja 5 – Wykrywanie kolizji

Celem gry jest unikanie zderzeń z nadlatującymi statkami przeciwnika. W tym celu manewrujemy naszym statkiem w dół i w górę. Jednak jeśli nastąpi zderzenie, na ekranie ma się pojawić efektowna eksplozja. Aby to zrobić, musimy mieć możliwość wykrywania kolizji – w momencie, gdy do niej dojdzie, wywołamy funkcję rysującą eksplozję.

Skorzystamy ze znanego z poprzednich lekcji sposobu, czyli połączymy funkcję sprawdzającą, czy nie doszło do kolizji, ze zdarzeniem odświeżania ekranu. Przed każdym odrysowaniem ekranu sprawdzimy, czy nasz statek nie zderzył się właśnie ze statkiem przeciwnika. Można to zrobić korzystając z gotowych rozwiązań do wykrywania kolizji, ale na potrzeby tego kursu i dla pełnego zrozumienia zastosujemy rozwiązanie  proste, ale całkowicie niezależne od dodatkowych funkcji czy bibliotek.

Kiedy można powiedzieć, że statki się zderzyły? Wtedy, kiedy obrazki statków stykają się krawędziami w pionie lub w poziomie. Na potrzeby tej gry przyjmiemy, że statki są prostokątne, mniej więcej tak:

kolizja1

i od tego momentu rozpatrujemy, czy nie nastąpiło zetknięcie się prostokątów:

kolizja2

Przy bardziej skomplikowanych kształtach rozpatruje się wielokąty lub kilka prostokątów, ale nie będziemy komplikować – w praktyce nie będzie to miało większego znaczenia.

Zderzenie (w poziomie) zajdzie, jeśli odległość pozioma między środkami prostokątów jest mniejsza niż odległość między środkami tych prostokątów w momencie, kiedy stykają się krawędziami. Odległość miedzy środkami stykających się prostokątów to 1/2 * a + 1/2 * b, czyli (a + b) / 2 (a – szerokość pierwszego prostokąta, b – drugiego).

kolizja3

Aktualna odległość (w poziomie) między środkami prostokątów to | x1 – x2 | (wartość bezwzględna z różnicy między współrzędnymi x środków obu prostokątów – czyli odległość pozioma). Kolizja nastąpiła więc, jeżeli spełniony jest warunek:

| x1 – x2 | < ( w1 + w2 ) / 2, gdzie x1 to współrzędna x pierwszego prostokąta, w1 to szerokość pierwszego prostokąta, a x2 i w2 – odpowiednio drugiego.

Taki sam warunek muszą spełniać współrzędne pionowe (musimy stwierdzić, że prostokąty zahaczają o siebie, a nie są np. jeden wysoko nad drugim). Jeśli jest spełnione poniższe (analogiczne) równanie:

| y1 – y2 | < ( h1 + h2 ) / 2

to prostokąty ‚zachodzą’ na siebie w pionie. Jeżeli prostokąty zachodzą na siebie jednocześnie w pionie i w poziomie – nastąpiła kolizja.

Teraz wykorzystamy te rozmyślania w praktyce.

Na początku kodu (ale pod definicją zmiennych statek i przeciwnik) wpisz

Kolizja nastąpi po spełnieniu następującego warunku:

Ten fragment kodu wpisz na końcu funkcji ruszajObiektami, która jest wywoływana przy każdym odświeżeniu ekranu. Od tego momentu w momencie zetknięcia statków na konsoli pojawi się napis „bum”. Kolizja została wykryta. Ponieważ na razie nic z tym nie robimy, na konsoli pojawi się cała seria napisów „bum” – tak długo, jak długo statki będą się stykały. Nas będzie interesował tylko pierwszy „bum” – po nim zatrzymamy grę i narysujemy na ekranie eksplozję – i to już w następnym odcinku kursu 🙂

Ćwiczenie

Jak wyglądałyby warunki dla kolizji, jeżeli statki potraktowalibyśmy jak okręgi o promieniach r1 i r2?

kolizja4

Rozwiązanie podam na koniec kolejnej lekcji.

Na koniec cały kod:

W następnej lekcji dodamy eksplozję (czyli koniec gry) i, działając konsekwentnie, przycisk do uruchomienia nowej gry.

Poprzednia lekcja | Następna lekcja