Tworzenie gier w JavaScript: kolizje – część druga

Wykrywanie kolizji jest zdecydowanie jednym z najważniejszych aspektów logiki tworzenia gier. Tworzenie gier w JavaScript nie wyróżnia się pod tym względem. W poprzednim poście opisałem jak wykrywać kolizje bazując na prostokątach granicznych. Jest to bardzo proste i wygodne podejście, jednak nie zawsze na tyle dokładne, na ile chciałby programista.

W dzisiejszym poście przedstawię inny sposób na wykrywanie kolizji. Bazuje on nie na prostokątach lecz na kołach. To powoduje, że w pewnych sytuacjach jest on o wiele dokładniejszy.

Tworzenie gier w JavaScript

Na początek małe demo. Wykorzystuje ono opisywaną dziś mechanikę. za pomocą strzałek można kierować robotem, przemieszczając go po pustyni. Jeżeli robot najedzie na kamień, wyda z siebie dźwięk. Warto zwrócić uwagę, że nawet gdy robot jest już prawie nad kamieniem, ale jeszcze go nie dotyka, kolizja nie jest rejestrowana.

robot1

Gdybym sprawdzał kolizję za pomocą prostokątów granicznych, program już dawno wykryłby kolizję. Zaznaczyłem umowny prostokąt w okół robota, aby było to wyraźnie widać.

Jak to się dzieje? Odpowiedź jest zaskakująco prosta. Zamiast sprawdzać czy dwa obiekty zajmują tę samą przestrzeń (jak to miało miejsce w przypadku prostokątów) sprawdzam, czy są one na tyle blisko siebie aby wywołać kolizję. Oto kolejny schemat:

robot2

To ten sam obrazek. Zaznaczyłem jednak na nim trzy odcinki: A, B oraz C.

Odcinek A to pozioma odległość pomiędzy środkami obu obiektów. Odcinek B to pionowa odległość pomiędzy środkami obiektów. Wszystkie odcinki razem, tworzą trójkąt prostokąty, którego przeciwprostokątna to odcinek C.

To właśnie odcinek C jest faktyczną odległością pomiędzy środkami obu obiektów. Dopóki odcinek C jest dłuższy niż suma długości promieni obiektów, obiekty nie stykają się. Promienie obiektów mam już dane. Były mi potrzebne aby narysować w programie okrąg. Ale jak znaleźć odcinek C?

Znalezienie długości odcinka C jest bardzo proste. Chyba każdy pamięta twierdzenie Pitagorasa. A podniesione do kwadratu plus B podniesione do kwadratu, daje C podniesione do kwadratu :).

Biorąc pod uwagę to wszystko, można napisać taką funkcję:

Funkcja ta przyjmuje dwa argumenty. Są to obiekty, między którymi sprawdzam wystąpienie kolizji. Wewnątrz funkcji obliczam długość odcinków A oraz B. Od współrzędnej x środka jednego obiektu, należy odjąć wartość współrzędnej x środka drugiego obiektu aby uzyskać długość odcinka A. W takim sam sposób sprawdzam długość odcinka B, używając współrzędnej y. Współrzędne środka obiektów są znane, ponieważ program potrzebuje ich aby narysować okrąg na płótnie (więcej o rysowaniu okręgów można przeczytać np tutaj).

Znak wyniku, nie jest ważny, ponieważ mierzę odległość, czyli wartość bezwzględną. Następnie symuluję potęgowanie długości odcinków a wyniki dodaję do siebie. Wszystko to traktuję metodą sqrt obiektu Math (metoda ta wyciąga pierwiastek z tego co ma podane w argumencie), i przypisuję wynik do zmiennej, która ma przechowywać wartość równą długości odcinka C.

Teraz wystarczy dodać do siebie długości promieni oby obiektów i wszystko czego potrzeba do sprawdzenia kolizji jest już znane.

na koniec funkcja zwraca wynik porównania długości odcinka C z sumą długości promieni. Jeżeli odcinek C jest krótszy, oznacza to, że obiekty stykają się, a funkcja zwraca true.

Tak może wyglądać kod wykorzystujący tę funkcje:

Co ciekawe, sprawdzany obiekt wcale nie musi być kołem. Wystarczy, że program ma dość danych aby móc umownie stworzyć koło w okół obiektu. Tak jest w przypadku robota w moim programie. Jest on rysowany jako prostokąt zawierający obrazek z arkusza klatek. Wystarczy, że podzielę jego szerokość na pół aby otrzymać długość umownego promienia. Gdy robot porusza się oprócz standardowych współrzędnych aktualizuję również współrzędne środka. Dzięki temu mam wszystkie potrzebne dane.

Zachęcam do przestudiowania kodu strony z programem, aby zobaczyć jak to działa 🙂

Reasumując, ten sposób na sprawdzanie kolizji, jest bardzo prosty a zarazem dość precyzyjny w wielu wypadkach. Wszystko to dzięki podstawowej wiedzy z geometrii 🙂 Ta metoda i metoda opisana wcześniej, dają programiście możliwości wykrycia większości kolizji w grach dwuwymiarowych 🙂

Mam nadzieję, że ten post pomoże w pisaniu kodu, który będzie wykrywał kolizje w waszych grach. Teraz kiedy już opisałem, jak efektywnie wykrywać kolizję, przyszedł czas na to aby podzielić się wiedzą o tym, jak robić to szybko i bez zbędnych obliczeń. Ale to już w następnym poście 🙂

Jeżeli masz jakieś pytania, możesz śmiało zadać je w komentarzach. Na każde na pewno odpowiem. Można też kontaktować się ze mną przez moją stronę na facebooku, którą swoją drogą zachęcam do polubienia 😉

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *