Autor Wątek: Kolizje 2D - z której strony kolizja?  (Przeczytany 3096 razy)

Offline Shusty

  • Użytkownik

# Wrzesień 07, 2012, 23:10:23
Problem pewnie prosty, ale już mam na razie dość stania w miejscu i myślenia, więc zwracam się do was o pomoc.

Weźmy na tapetę platformówkę.  Kolizje 2D zwłaszcza prostokątów, rzecz prosta. Biorąc pod uwagę kierunek i prędkość można wywnioskować, której strony mamy kolizję.
 Co jednak jeśli musimy wykryć jakoś czy pod nogami mamy podłoże, a kiedy go nie mamy, aby zacząć spadanie? Jeśli postać spada, to mamy vY i sprawa prosta, ale jeśli postać sobie idzie w poziomie i musimy wiedzieć czy mamy kolizję od dolu, a może od góry, bo coś nam na głowę spada?

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Nsuidara

  • Użytkownik
    • Site

# Wrzesień 08, 2012, 00:42:41
Cytuj
Weźmy na tapetę platformówkę.
niestety wolę Asurę z GW2 ^^



Cytuj
Co jednak jeśli musimy wykryć jakoś czy pod nogami mamy podłoże, a kiedy go nie mamy, aby zacząć spadanie?
Zasadniczo jeżeli mamy zrealizowaną strukturę i metody dla "Collision Detection"

Postać posiada wektor poruszenia ( ... prędkość X i Y )
Wystarczy że mamy jakąś metodę która zwraca wszystkie kolizje które nastąpiły dla postaci...
Wtedy gdzieś tam zdefiniowałeś "platformę" i działasz jeżeli postać ma kolizję od dołu z platformą, to zamiast pełną prędkość Y dajesz odstęp między wykryciem podłogi a postacią (tzn. aby całkowicie wylądowała na platformę) lub też zerujesz... albo albo pomijasz współczynnik grawitacyjny.

Oczywiście jeżeli postać wyjdzie po za podłogą czyli będzie "przepaść" to grawitacja będzie znowu działać bo nie będzie kolizji.

Kwestią teraz jak został zdefiniowany obszar postaci dla (nóg) ponieważ będzie mógł wyjść zahaczając o platformę-przepaść spory kawałek :]


Cytuj
Kolizje 2D zwłaszcza prostokątów, rzecz prosta.
Cytuj
Biorąc pod uwagę kierunek i prędkość można wywnioskować, której strony mamy kolizję.
Cytuj
Jeśli postać spada, to mamy vY i sprawa prosta, ale jeśli postać sobie idzie w poziomie i musimy wiedzieć czy mamy kolizję od dolu, a może od góry, bo coś nam na głowę spada?
Ogólnie dla mnie paradoksalny temat, ponieważ kolizje, kierunek itp to jest prosta rzecz... to jaki problem jest w tym problemie ?

Wykrywasz dla postaci kolizję ? (dynamiczne i statyczne)
Więc w czym problem... z której strony była kolizja ?
Obliczasz wektor różnic położenia obiektów i interpretujesz ...

Ogólnie dzisiaj napisałem własny system detekcji w AS3 http://nsuidara.pl/img/APP/MainV008.swf ( sterowanie WASD )kolizji i pracuję nad nim...
ubóstwiam AS3 ze względu na jedno , dość łatwo definiować sobie obiekt {A:0,B:1,C:3, ...} i mamy obiekt do którego potem możemy dodać .D = 5 :F (możliwe ze podczas kompilacji to wykrywa all... ale podczas pisania to jest piękne :D )

Zastanawiam się jak mam drzewo czwórkowe i aż takie dynamiczne obiekt jak przedstawiłem w Flashu...
nie wystarczy zmiana pozycji czujnika kolizji... ale co ? co przed przesunięciem usuwać z drzewa kolizji... i po przesunięciu dodać ?
« Ostatnia zmiana: Wrzesień 08, 2012, 01:18:40 wysłana przez Nsuidara »

Offline .:NOXY:.

  • Użytkownik
    • Profil

  • +2
# Wrzesień 08, 2012, 11:23:44

Offline Shusty

  • Użytkownik

# Wrzesień 08, 2012, 16:59:33
Niby tak, ale piszę w Javie, a nie C++

Co do rozwiązania, to najbardziej mi się podoba ta z grawitacją.

Offline MaxGarden

  • Użytkownik
    • Profil na warsztacie

# Wrzesień 08, 2012, 17:23:51
No to może JBox2d? http://www.jbox2d.org/

Offline Shusty

  • Użytkownik

# Wrzesień 08, 2012, 18:17:19
Z Box2D nie ma problemu, ale JBox2D nawet manuala, żadnego znaleźć nie mogę.

Offline MaxGarden

  • Użytkownik
    • Profil na warsztacie

# Wrzesień 08, 2012, 19:32:27
Cytuj
For documentation, you can always refer to the included Javadocs, but JBox2D is very closely related to the C++ Box2D, so please see the C++ documentation at Box2D.org which, apart from minor name changes (b2Body -> Body, for instance, and in the Java port methods are camel-cased instead of capitalized), should apply equally well to JBox2D. Also see the source code of the demos (the org.jbox2d.testbed.tests package) to see how various effects are achieved in JBox2D.

Offline Shusty

  • Użytkownik

# Wrzesień 09, 2012, 00:39:35
Na razie Box2D nie jest pilnie potrzebny, ale jest problem, bo napisałem dobry algorytm wykrywający z kórej strony mamy kolizję, jednak rzadko kiedy jest to wykrywane.

Dla przykładu kolizja z dołem.
Najpierw sprawdzam, czy w ogóle wystąpiła kolizja, a później:

(...)
if(y1+h1 < y2 && y1+h1+vy1 >= y2){
            return Collision.DOWN;
         }
(...)


(h: heigt w: width vy1: grawitacja)

przy czym vy1 wynosi 0.2f, więc rzadko kiedy przy 50fpsach udaje się uchwycić ten moment. Przy dopiero vy1== 6.0f  w 70% zostaje to wykryte. Co mam z tym fantem zrobić? vy 0.2f to i tak szybkie spadanie postaci (vy1:0.2 czyli 0.2 px na milisekundę).
« Ostatnia zmiana: Wrzesień 09, 2012, 01:11:54 wysłana przez Shusty »

Offline Nsuidara

  • Użytkownik
    • Site

  • +1
# Wrzesień 09, 2012, 04:01:34
Zasadniczo Tobie nikt nie odpowie na "Co mam z tym fantem zrobić?" z prostego powodu, nie wiemy w jakich momentach masz wykrywanie kolizji, a wynika że nie co klatkę ^^ a powinno być co klatkę.

Możliwe że postać przeskakuje ? tzn. za szybko spada ?
Wtedy musisz uwzględnić czas który jest między klatkami (FPS)
tzn. np.
Ogólnie zdefiniowałem sobie że moja postać ma poruszać się 300px na sekundę...
Posiada też prędkość czym dłużej trzymam jakiś klawisz tym przyspiesza...
Jednakże maksymalna prędkość to u mnie :
Max = "max_odległość" * "różnica czasu miedzy klatkami w ms" / 1000ms
innym słowem np. 300px * 34/1000 = 10,2px co klatkę przemieszcza się postać...

Jeżeli platforma jest linią, to sprawdzić musisz czy odcinek który powstaje między postacią a jej następnym przesunięciem nie przecina czasem prostą jak przecina to skrócić ten odcinek do prawidłowego momentu... :]

Zastanawiam się odnośnie "(SAT) for Collision Detection"
Ogólnie SAT jest jakby rzutowanie cienia i czy czasem część cienia nie pokrywa się z drugim obiektem...

A przykładowo (teraz wpadłem na taki pomysł) jeżeli mamy wielokąty no np. Trójkąt ABC i Prostokąt 1234
Zastanawiam się czy sprawdzenie przecięcia odcinków Trójkąta z odcinkami Prostokąta by nie wystarczyło ?
Nie było by do dobre ? rozwiązanie ?

a może http://physics2d.com/content/gjk-algorithm ? :F
« Ostatnia zmiana: Wrzesień 09, 2012, 04:52:50 wysłana przez Nsuidara »

Offline Shusty

  • Użytkownik

# Wrzesień 09, 2012, 14:00:00
Wykrywanie kolizji jest co klatkę.
U mnie to 20px na sekundę, co przy pętli stałokrokowej i 60 fpsach (które narzuca vsync) daje: 20/60=0,(3) czyli przy tylu fpsach minimalne przesunięcie do jakiego może dojść to 0,(3)px w klatce, a moja postać spada z prędkością 0,2

Oczywiście przy 1000fpsach, które uzyskuję w okienku, a nie fullscreenie gra działa dobrze.
Na razie mam mało eleganckie rozwiązanie na to, ale to tylko tymczasowe i szukam innego rozwiązania bo to ma wady.

Co do GJK jeszcze zajrzę w wolnym czasie, bo muszę sprawdzić czy pozwala wykrywać, z której strony mamy kolizję. Po drugie takie definiowanie jest bardziej skomplikowane, niż po prostu prostokąty, które na razie wystarczają.

Offline Nsuidara

  • Użytkownik
    • Site

# Wrzesień 09, 2012, 15:56:08
Ogólnie ludzie piszą/mówią że GJK jest dość prosty a nawet nie wytłumaczą wszystkiego porządnie...

Według mnie wystarczy sprawdzić od której strony (ten mutant figura) dotyka pkt. 0,0 :F

Offline Shusty

  • Użytkownik

# Wrzesień 09, 2012, 16:45:37
Zrobiłem pętlę stało krokową o bardzo małym TIME_STEP = 3000000 (nanosekund czyli 0,03 sekundy),  teraz aktualizacja stanu gry odbywa się kilka razy zanim nastąpi draw(), co rozwiązuje problem.

W przyszłości jednak i tak planuję wdrożyć SAT lub GJT, jednak i tak potrzebuję wtedy wiedzieć wtedy z której strony mam kolizję.

Pewnie gdybym pisał grę z jakiegoś tutka i tylko modyfikował nie miałbym takich problemów, ale wszystko od zera piszę sam i mam z tego radochę póki co.

Offline Nsuidara

  • Użytkownik
    • Site

# Wrzesień 09, 2012, 20:01:33
Zrobiłem pętlę stało krokową o bardzo małym TIME_STEP = 3000000 (nanosekund czyli 0,03 sekundy),
ms = 10^-3 np. 30ms = 0,030s
ns = 10^-9 np. 30ns = 0,000000030s ( http://pl.wikipedia.org/wiki/Nano )...
3 000 000ns = 0,003 000 000s = 0,003s = 3ms
Zastanawiam się w jakim języku jest możliwe zliczenie czasu w Nano...

teraz aktualizacja stanu gry odbywa się kilka razy zanim nastąpi draw(), co rozwiązuje problem.
Zastanawiające rozwiązanie jednakże jeżeli nie będziesz mieć dobrej struktury przechowywania elementów kolizji tzn. (czujników) to zastanawiam się jaki spadek potem będzie na FPSach :F przy 100-300 obiektach :F
 
W przyszłości jednak i tak planuję wdrożyć SAT lub GJT, jednak i tak potrzebuję wtedy wiedzieć wtedy z której strony mam kolizję.
Zawsze trzeba wiedzieć z której strony jest kolizja ^^ tylko trzeba odpowiednio interpretować to co mamy dane...

Pewnie gdybym pisał grę z jakiegoś tutka i tylko modyfikował nie miałbym takich problemów, ale wszystko od zera piszę sam i mam z tego radochę póki co.
Zasadniczo nie lubię przeglądać czyjegoś kodu (zwłaszcza gierek) niekiedy gubię się :D w swoim kodzie po miesiącu przerwy... a co mówić...

Jednakże Algorytmy to już inna kwestia to jest bardzo przydatna wiedza :D
A jednak GJT jest naprawdę prostą metodą :D

Offline Shusty

  • Użytkownik

# Wrzesień 09, 2012, 20:59:16
Zastanawiam się w jakim języku jest możliwe zliczenie czasu w Nano...

Java

Zawsze trzeba wiedzieć z której strony jest kolizja ^^ tylko trzeba odpowiednio interpretować to co mamy dane...
No to ja mam przy gjk problem z tym...

Offline Nsuidara

  • Użytkownik
    • Site

# Wrzesień 09, 2012, 22:25:50
http://physics2d.com/content/gjk-algorithm // czerwone pkt. możesz przesunąć :]
Zobacz jak zachowuje się bryła z niebieskimi-punktami odnośnie + (środka) 0,0 współrzędnych :]
Widzisz jedna z cech...
Dodatkowo (nie jestem pewny - dziś mnie strasznie głowa boli :D) to zawsze masz można powiedzieć prostą z ów ... które są tworzone z zbioru pkt. A i B... więc penie można uzyskać proste które przecinają się ? dotykają itp ? i uzyskać odległość między tymi prostymi itp ? / albo jak głęboko wchodzą w siebie...

Zobaczyć trzeba co mamy i co z tego można zinterpretować...


Możesz brać środek danej bryły lub pseudo-środek (bo nie każda bryła ma środek xD) no i zrobić wektor obu figur..
AB = [B.x-A.x, B.y-A.y] no i interpretujesz z której strony jest dotknięcie...