Kolizja 2d

0

Witam.
Mój problem polega na wykryciu kolizji 2d na układzie współrzędnych.
Obiekt o kolorze niebieskim może poruszać się w 4 kierunkach(góra, dół, prawo, lewo). Jest to obiekt prostokątny, gdzie mogę stworzyć na jego podstawie new Rectangle(obiekt.x, obiekt.y, obiekt.getWidth(), obiekt.getHeight()), lecz podłoże jest zwykłym obrazkiem typu
BufferedImage, z którego nie mogę już stworzyć prostokąta i sprawdzić czy na siebie nachodzą tworząc kolizję.
Jak powinien działać algorytm wykrywania kolizji między obiektem a mapą?
Poniżej załączam przykładowy obrazek objaśniający co nieco problem.

0

Możesz skorzystać z per-pixel collision.

0

W takich przypadkach często stosuje się "maskę" terenu jako osobny obraz np. pola przez które można przejść są czarne, a inne np. zielone.
Wyświetlasz swój obraz natomiast kolizje badasz na tej masce odnosząc się do pozycji obiektu i koloru maski np.:

Sprawdzasz jaki kolor ma maska w punkcie będącym środkiem dolnego boku twojego prostokąta za pomocą np. maska.getRGB(punktX,punktY) (zwraca w formacie 0xRRGGBBAA); czarne -> obiekt może opaść, zielone -> "stoi" na podłożu

0
franek1101 napisał(a):

W takich przypadkach często stosuje się "maskę" terenu jako osobny obraz np. pola przez które można przejść są czarne, a inne np. zielone.
Wyświetlasz swój obraz natomiast kolizje badasz na tej masce odnosząc się do pozycji obiektu i koloru maski np.:

Sprawdzasz jaki kolor ma maska w punkcie będącym środkiem dolnego boku twojego prostokąta za pomocą np. maska.getRGB(punktX,punktY) (zwraca w formacie 0xRRGGBBAA); czarne -> obiekt może opaść, zielone -> "stoi" na podłożu

Najlepiej to zrobić własny system mapy w którym ustalisz jakie punkty będą kolizyjnymi,

0

W miejscu w którym znajduje się Twój obiekt sprawdzasz współrzędne x jego narożników i pod tymi współrzędnymi na obrazku lub mapie kolizji pasującej do tego obrazka sprawdzasz czy wysokość terenu y jest większa czy mniejsza. Jeżeli mniejsza, to Twój obiekt włazi w teren (ma kolizję) tych narożników, jeżeli większa, to jest ponad nim. Gdy wszystkie punkty kolidują, to Twój obiekt jest poniżej zielonego terenu, a gdy żaden, to jest w całości powyżej.

To mniej więcej napisali poprzednicy w swoich postach. Mapa kolizji to po prostu maska reprezentująca nieprzenikalne ściany. Najprościej ją zrobić biorąc do edytora graficznego oryginalny obrazek i zamalowując jednym (tym samym) kolorem wszystkie miejsca nie do przebycia. Na koniec najczęściej się ją konwertuje na obrazek 1-bitowy (zwykle rysowany jako czarno-biały) dzięki czemu każdy piksel jest reprezentowany tylko jednym bitem. I to właśnie jest ta "prawdziwa" maska, gdzie sprawdzając współrzędne otrzymujesz prostą informację: 1 - kolizja, 0 - brak kolizji (lub odwrotnie).

0

jak dotąd zrobiłem tak: podczas każdego ruchu obiektu pobieram getRGB piksela o wsp, obiekt.x i obiekt.y, potem sprawdzam czy różni się z kolorem tła(które jest jednego koloru, a mapa może mieć dowolne), jeśli tak odpowiednio modyfikuje obiekt.x i obiekt.y, aby "utrzymywał" się na mapie.
Rozwiązanie to działa tylko ma jeden minus - tło musi być cały czas jednego koloru.
Co do rozwiązania wymienionego wyżej to mądre posunięcie. Tworze sobie osobny gif który opisze mi mape na "czarno-biało", czarny - kolizja, biały opadamy(y--).
Tylko tutaj pytanie jak mogę wstawić tą maskę, żeby nie była widoczna oraz pobierać aktualne getRGB?
chciałem jeszcze podziękować za wszystkie odpowiedzi :)

1

Maskę zrób sobie w planie 1-bit (nie musi być koniecznie skompresowana - oszczędność nie będzie wielka) i tak jak napisał kolega nigdzie jej nie rysujesz, tylko wczytujesz do pamięci. Taki typ obrazka jest też nazywany Black and White - to najprostszy i najstarszy rodzaj obrazu, który do dzisiaj istnieje w działaniu już tylko w maszynach faksowych oraz właśnie jako maski w grach i programach graficznych.
Możesz też skonwertować ją na boolean[][] czy byte[][], ewentualnie jako BitSet[] gdzie każda linia pikseli będzie jednym obiektem BitSet. Konwersja jednak nie jest specjalnie potrzebna bo pobieranie wartości piksela maski obrazka 1-bitowego wczytanego do pamięci jest całkowicie efektywne.

Na dodatek gdybyś chciał robić grę taką jak Worms, Scorched Earth czy Boulder Dash, gdzie wybuchy lub ludki niszczą teren, to wtedy oprócz jakiejś eksplozji na głównym obrazku robisz w tym samym miejscu dziurę w masce o tym samym promieniu i masz już w tym miejscu obszar bez kolizji.

0

Właśnie realizuje grę Scorch z "wormsową" mapą i wybuchami niszczącymi planszę.
Dzięki wielkie za podrzucenie pomysłu jak wrócę z pracy zabiorę się za to, myślę że nie będzie
większych problemów :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1