Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

dynamika i kolizja w grach 2D

Ostatnio zmodyfikowano 2018-03-19 19:33
Autor Wiadomość
michal11
» 2018-03-05 01:41:14
Jak to nie masz? To jak testowałeś ten kod?

szkoda by było znowu się namęczyć - jak by nie było - na darmo.
Na pewno nie na darmo, na nieudanych projektach i pomysłach najwięcej się uczysz.

plus jest taki, że przy znalezieniu pierwszej niepasującej cechy zwraca false
Nie ma to znaczenia, w 99.9% przypadków badania złożoności algorytmów przyjmuje się wariant pesymistyczny.
P-169769
latajacaryba
Temat założony przez niniejszego użytkownika
» 2018-03-05 01:54:33
Jak to nie masz? To jak testowałeś ten kod?
Ummm... no cóż... ale kompiluje sie!

Poważnie: nie sprawdzałem, bo chytry plan przewidywał, że od razu wezmę się za tworzenie tego systemu mapa+kolizje i to bedzie dobrym testem. Ale masz racje, lepiej to sprawdzić, skrobnę coś i wrzucę.
P-169770
latajacaryba
Temat założony przez niniejszego użytkownika
» 2018-03-15 01:26:11
Okazało się, że napisanie tego to nie taka prosta sprawa, bo postanowiłem do przetestowania CO od razu zrobic - wspomnianą - mapę + kolizje. Niestety, na jaw wyszedł straszny problem, który opiszę;

Otóż pomyślałem, że fajnie by było wiedzieć, z której strony zaszła kolizja. Mozna zrobić to dzięki analizowaniu prędkości - jeśli poruszamy sie w osi X to na pewno kolidujemy prawym lub lewym bokiem, analogicznie oś Y. Wydawałoby się, że problem rozwiązany, ale nie!

Bo co nie wziałem pod uwagi następujących sytuacji:

1) jedno ciało porusza sie w osi X a drugie w osi Y przez co wywnioskowanie z której strony zaszła kolizja nie jest już takie proste. Nadal jest możliwe, ale niestety zasobochłonne ;(

2) oba ciała poruszają się np. tylko w osi X i tu wydaje się, że nie ma problemu, po zderzeniu zatrzymujemy oba ciała. Nic bardziej mylnego. Analogią będą tu samochody na jezdni:

  a)Jeśli kierunek poruszania się jest w przypadku obu obiektów taki sam (czyli jedziemy prawym pasem, przed nami jedzie inne auto) i zajdzie kolizja, to   
    obiekt który "wpakował się" w obiekt przed nim wytraca prędkość. Tylko on (jeśli wjedziemy w tył auta jadącego przed nami, to my wyhamujemy).

  b) wektory prędkości obiektów mają przeciwne zwroty - auta jadą na siebie i zderzają się czołowo - oba hamują.

Tu mała dygresja, ja przypominam, że to będzie całkiem sporo ifów i porównywania i może to odbić sie na wydajności

3) I coś, przy czym już kompletnie wymiękam. Wyobraźcie sobie taką sytuacje: gracz wchodzi w jeża. Tak, jeża. Jeż oczywiście jak to ma w zwyczaju, kłuje go i (tylko ten, gwoli ścisłości)odrzuca gracza od siebie (to taki specjalny jeż). Jednak gracz ma na sobie zbroje, która pacyfikuje jeże po kontakcie z nimi. A więc wygląda na to, że jeż kłujnie gracza, a ten "zniknie" go? Nie.

Bo sprawdzanie kolizji odbywa się w następujący sposób: wybieramy jeden obiekt i dobieramy mu sąsiadów, z którymi fizycznie jest (ze wzgledu na odległość) w stanie kolidować. Takich sąsiadów sprawdzamy dla danego obiektu.

Załóżmy, że pierwsze sprawdzane są kolizje dla jeża. Jeż znajduje gracza jako sąsiada, zadaje obrażenia i odrzuca go.
Teraz gracz sprawdza kolizje. No, jeż jest blisko więc nawet może być sąsiadem, ale po chwili okazuje się, że jest za daleko. Nie ma kolizji. Dlaczego? No bo gracz został odrzucony. Jego zbroja okazała się więc zbędna.

No to może sprawdzać kolizje raz, i wykonywać obie operacje (gracza na jeżu i jeża na graczu)?
C/C++
if( jez.sprawdz_kolizje( gracz ) )
{
    jez.koliduj( gracz );
    gracz.koliduj( jez );
}
Nie, ponieważ jak pisałem, program sprawdza kolizje dla gracza a potem dla jeża (lub na odwrót), więc wyglądałoby to tak:

C/C++
if( jez.sprawdz_kolizje( gracz ) )
{
    jez.koliduj( gracz );
    gracz.koliduj( jez );
}
Dla jeża, a zaraz to samo wywołałoby się dla gracza.
No i powiedzcie, co ja mam zrobić...
ps. wybaczcie za tego jeża, miałem wcześniej lepszy przykład, ale wypadł mi z głowy
P-170022
darko202
» 2018-03-15 10:00:16
1.
na jaw wyszedł straszny problem ...
jest "III zasada dynamiki Newtona"

" Oddziaływanie dwóch ciał jest zawsze wzajemne. Jeżeli jedno ciało działa na drugie pewną siłą, to
drugie działa  na ciało pierwsze siłą taką samą co do wartości i kierunku, a o zwrocie przeciwnym."

na studiach miałem na ćwiczeniach z fizyki eksperymenty " zderzanie dwóch kulek o różnych masach pod różnymi kątami "
są proste wzory - w świecie idealnym wystarczyć powinno pominąć grawitację (ewentualnie)

dlatego nie rozumiem problemu

ps.
jeż też pod to podpada :)

2.
przy zmianie tematu - otwieraj nowy wątek
inaczej łamiesz zasady forum
P-170024
latajacaryba
Temat założony przez niniejszego użytkownika
» 2018-03-17 23:45:22
dopiero dziś zauważyłem, że post mi sie nie dodał, no cóż... bywa.

@darko202
myślałem o tym, natomiast w tej grze implementacja siły nie ma sensu. Postać ma się zatrzymać i koniec.

aktualnie zrobiłem to sprawdzając kierunek ruchu (np. jeśli oba obiekty poruszają sie w prawo i nastąpi kolizja, to zatrzyma się obiekt który jest po lewej (czyli wszedł w obiekt po prawej))

Ale nadal niestety nie znalazłem rozwiązania z pkt. 3. Napisałeś, że nie rozumiesz problemu, także spróbuję go wyjaśnić jeszcze raz:

W grze jest kolekcja obiektów, które mogą ze sobą kolidować, dla uproszczenia uznamy, że mamy ich 2 - obiekty A i B

A[n]
B[n+1]
Dla każdego z nich sprawdzamy, czy zaszła kolizja z innym obiektem (nie sprawdzamy oczywiście całej kolekcji, zopytmalizowałem to)

Teraz obiekt A sprawdza kolizje z obiektem B. Kolizja występuje i obiekt A wywołuje na obiekcie B jakieś tam swoje czynności (np. zadaje obrażenia itp) ale jak sie okazuje, jedna z tych czynności jest odrzut, a więc obiekt A odrzuca na jakąś odległość od siebie B.

Teraz sprawdzana jest kolizja dla obiektu B. Okazuje się, że w tym momencie nie koliduje on z A (bo został odrzucony / teleportowany). Wynik - obiekt A zadziałał na B, ale B nie zadziałał na A.

C/C++
if( kolizja( A, B ) )
{
    A.wykonajCzynnosci( B );
}

if( kolizja( B, A ) ) // to juz nie zachodzi
{
    B.wykonajCzynnosci( A );
}

Rozwiązaniem mogłaby być sytuacja, w której po sprawdzeniu kolizji oba obiekty wykonują swoje czynności na sobie nawzajem (A na B i B na A).
To byłoby rozwiązanie dobre, gdyby nie fakt, że zaraz ponownie zostanie sprawdzona kolizja - już nie dla obiektu A, lecz B - efektem będzie ponowne wywołanie tych funkcji:
C/C++
if( kolizja( A, B ) )
{
    A.wykonajCzynnosci( B );
    B.wykonajCzynnosci( A );
}

if( kolizja( B, A ) ) // to moze zajsc lub nie - A i B mogly w poprzednim if'e sie od siebie odsunac, ale nie musialy!
{
    B.wykonajCzynnosci( A );
    A.wykonajCzynnosci( B );
}

//efekt? podwojne wywolanie tych samych funkcji (np. zadanie obrazen)

przy zmianie tematu - otwieraj nowy wątek
IMO nadal odnosi się do Collision Object o którym piszemy już od 3 stron, chyba, że właśnie o niego Ci chodzi, to wtedy tak, przyznaje, mój błąd.
Jeśli administrator/moderator będzie miał problem to przeniosę, choć pewnie ciężko byłoby tłumaczyć od początku o co chodzi z tym Collision Objectem a tu wystarczy cofnąć sie o stronę.
P-170065
Saran
» 2018-03-18 08:36:18
No to zmień nazwę tematu na "Implementacja fizyki 2D w grze"
P-170068
darko202
» 2018-03-19 13:49:54

1.

... w tej grze implementacja siły nie ma sensu ...
to bardzo mocne stwierdzenie :)

z definicji siły (pierwszej) jest to : masa * przyspieszenie.
http://www.fizykon.org​/dynamika​/dyn_sila_definicja_zasady_dynamiki.htm

jeśli nawet masa może nie mieć znaczenia (tzn. zawsze  m = 1) to jeśli mówimy o kolizjach obiektów to obiekty te muszą mieć jakieś przyspieszenie
ale "III zasada dynamiki Newtona" nadal działa co do kierunku zwrotu siły powodującej dalszy los obiektu

oczywiście w niektórych przypadkach można zdefiniować ja na 0 po kolizji.
ale w pozostałych przypadkach bardzo dokładnie określa kierunek i prędkość obiektu po odbiciu

dla mnie ta interpretację siły według ww. zasady definiujesz w grze -> musisz.
problemem jest to, że tego nie widzisz :)
próbujesz jeszcze raz zdefiniować to co zostało już zdefiniowane.

uważaj na "spadające jabłko ..."  :))

2.

Teraz obiekt A sprawdza kolizje z obiektem B. Kolizja występuje i obiekt A wywołuje na obiekcie B jakieś tam swoje czynności (np. zadaje obrażenia itp) ale jak się okazuje, jedna z tych czynności jest odrzut, a więc obiekt A odrzuca na jakąś odległość od siebie B.

Teraz sprawdzana jest kolizja dla obiektu B. Okazuje się, że w tym momencie nie koliduje on z A

pamiętam taki problem
czy można posortować tablicę przy użyciu 2 zmiennych ?
tzn. wiem że mam zamienić element tab z tab[j]  -> musimy użyć trzeciej zmiennej
 
podobnie Twój problem kolizja A i B
czy bardzo Cię zaboli jak stworzysz chwilową kopię np. A' a wtedy

kolizja(A,B)
kolizja (B,A')

 
3.
sorry, że nie czytałem wcześniej dokładnie całej dyskusji do tego tematu,
ale po przeczytaniu nadal podtrzymam swoje zdanie o konieczności zakładania kolejnych wątków.

jeśli chodzi o pytanie o koncepcję jak mam zrobić dany problem to OK, ale jak po otrzymaniu odpowiedzi zadajesz kolejne N pytań już na inne tematy, a potem po raz kolejny, to naginasz zasady.

Nie pomaga Ci to też skoncentrować się na kolejnych problemach

zadałeś 7 pytań -> otrzymałeś 3 odpowiedzi -> wszyscy myślą, że już masz o co pytałeś (nie czyta się zakończonych problemów -> zwłaszcza długich), a Ty się denerwujesz, ze nie otrzymujesz odpowiedzi 
zadajesz więc kolejne pytania .....

można prościej : jedno pytanie -> jeden wątek


Powodzenia !
P-170105
latajacaryba
Temat założony przez niniejszego użytkownika
» 2018-03-19 19:33:51
No dobra, prawdopodobnie znalazłem rozwiązanie. Niestety, nie zrozumiałem za bardzo, co miałeś na myśli. To znaczy... po co mi A'? Po co mam tworzyć kopie A? To nie eliminuje powtórzenia. Ewentualnie coś źle zrozumiałem. W każdym razie ten wątek zamykam, gdybym dalej miał z tym problem, to otworzę nowy.

A rozwiązanie wygląda w ten sposób, że mamy 2 sytuacje:

1) obiekty A i B są materialne, jakby "stałe" - czyli że gracz czy cokolwiek nie może wejść w taki obiekt - np. głaz, albo budynek. Trawa nie jest takim obiektem, bo da sie w nią wejść - stoimy pośród trawy. Co logiczne to to, że wykrywając kolizje ustawimy gracza przed tym obiektem (no bo przecież nie pozostawimy go tak w tym głazie, nie jesteśmy tacy okrutni). Wiemy więc, że nie będzie on już kolidował z tym kamieniem, stojąc obok niego. Dlatego w trakcie sprawdzania kolizji wykonujemy zarówno A.koliduj(B) jak i B.koliduj(A) - bo wiemy, że już nie będą ze sobą sie stykać.

2) obiekty są "niestałe" lub niematerialne, czyli możemy w taki obiekt wejść (duch, zarośla trawy). Wtedy gracz nie zostanie ustawiony przed trawą czy duchem (w końcu może w nich wejść). Dlatego przy sprawdzaniu kolizji

Trawa -> gracz
zostanie wywołane
Trawa.koliduj(gracz);

A w wykrywaniu

gracz -> Trawa
gracz.koliduj(Trawa);

Cóż, ciężko mi to wytłumaczyć, więc posłużę się rysunkiem
https://zapodaj.net​/b21edcbe9b5cb.png.html

Temat zamykam.
P-170109
1 2 3 « 4 »
Poprzednia strona Strona 4 z 4