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

Kolizja - trudny orzech do zgryzienia

Ostatnio zmodyfikowano 2013-02-23 18:08
Autor Wiadomość
RazzorFlame
Temat założony przez niniejszego użytkownika
Kolizja - trudny orzech do zgryzienia
» 2013-02-21 11:06:59
No niee, nie chodzi mi o samo pojęcie, i zaimplementowanie kolizji, żebyście sobie nawet nie myśleli. Chodzi o coś trudniejszego. Nie chodzi o pixel-perfect ani coś w tym stylu. Chyba większość osób grała w jakąś platformówkę typu Mario. No i tu jest taki właśnie twardy orzech, w którym sobie nie dałem rady. Nie pisze projektu z tym związanym, ale na przyszłość się przyda a przecież kto nie posuwa się do przodu ten się cofa. Niedawno jednak próbowałem to ogarnąć, ale troche nie wychodziło. Kolizja działała fajnie, ale właśnie nie dokładnie jak bym chciał. Wyglądało to tak: Jest obiekt1 i obiekt 2. Poruszam się obiektem nr.1 i w zależności w jakiej kolejności będę sprawdzał kolizje (czy nastąpiła z boku, czy z góry itd) to jeśli nastąpiła kolizja, te 2 ostatnie są sprawdzane na końcu, (chyba że dam przed if - else) więc nawet gdyby kolidował obiekt 1 z ob. nr 2 od lewej strony to nie zostanie on zablokowany, tylko przy dalszym naciskaniu klawisza w prawo obiekt przesuwa się do góry aż przestanie działać kolizja. Wniosek: Dobrze sprawdzane są tylko 2 strony (zależnie od kolejności). Chodzi mi o kolizje, która działać będzie, nie tylko kiedy obiekt się przesuwa co 1 piksel, tylko np. 1.3. Wtedy już jest ciężej. Dlatego pytam was. W google wpisywałem: "C++ Collision from sides" czy coś w tym stylu. Wyskakiwały przykłady ze strony lazyfoo.net ale niestety nie działało. Autor/ka tej strony obliczała tam tylko kanty i później sprawdzała czy nie nachodzą na siebie. Jednak, co jeśli chciałbym sprawdzić czy kolizja nie nastąpiła od góry? Sprawdzić czy lewy górny lub prawy górny kant nie nachodzi? To się mija z celem bo nie można by było rozróżnić czy kolizja nastąpiła z boku czy z góry.

Edit:
Ale chyba mam pomysł. Czy zadziałałoby takie coś:
C/C++
stronaKolizji SprawdzKolizjeOdStrony( obiekt ob1, obiekt ob2 )
{
    if( kolizja() == strona_LEWYGORNY )
    {
        if( ob1.x - ob2.x > ob1.y - ob2.y ) return strona_LEWA;
        else return strona_GORNA;
       
    }
    //...
   
}
Coś mi mówi że takie coś by zadziałało. Zaraz to sprawdzę i powiem czy działa czy nie, ale można się wypowiadać :)
P-76607
unimator
» 2013-02-21 16:17:15
Każdą kolizję prostokątów powinieneś móc sprawdzić za pomocą takiej funkcji:
C/C++
bool kolizja( int x1, int y1, int h1, int w1, int x2, int y2, int h2, int w2 )
{
    if(( y2 + h2 < y1 && x2 + w2 < x1 ) ||( y2 + h2 < y1 && x2 > x1 + w1 ) ||( y2 < y1 + h1 && x2 + w2 < x1 ) ||( y2 < y1 + h1 && x2 > x1 + w1 ) ) return false;
    else return true;
   
}
Gdzie:
x, y - pozycja górnego, lewego wierzchołka
h - wysokość obiektu
w - szerokość obiektu
P-76617
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-02-21 19:24:03
Dużo do tematu nie wniosłeś bo nie o to mi chodzi. Zapewne nie przeczytałeś dokładnie - chodzi mi o bardziej złożoną kolizję. To jest fragment z tutoriala EasyKodera, nie jest to poprawne wykrywanie kolizji.
P-76652
unimator
» 2013-02-21 19:56:28
Chodzi mi o kolizje, która działać będzie, nie tylko kiedy obiekt się przesuwa co 1 piksel, tylko np. 1.3.
Zamiana int-ów na floaty nie pomaga?


Jednak, co jeśli chciałbym sprawdzić czy kolizja nie nastąpiła od góry? Sprawdzić czy lewy górny lub prawy górny kant nie nachodzi?
Zakładam, że kolidują prostokąty:
Obiekt 1 - na górze
Obiekt 2 - na dole

Kolizja nastąpi wtedy gdy:
prosta zawierająca dolne współrzędne wierzchołka Obiekt 1 znajdzie się na równi prostej zawierającej górne współrzędne Obiekt 2
oraz
prosta zawierająca górne współrzędne wierzchołka Obiekt 1 znajdzie się ponad prostą zawierającą górne wierzchołki Obiekt 2 (lub którykolwiek punkt górny Obiekt 1 znajdzie się ponad którymkolwiek innym punktem Obiekt 2)
oraz
co najmniej jeden punkt Obiekt 1 leży wewnątrz pola figury ograniczonej prostymi:
a) zawierającą prawe punkty Obiekt 2
b) zawierającą lewe punkty Obiekt 2

Chyba nic nie pominąłem, możesz to sobie rozrysować dla jasności. Analogicznie wygląda kolizja z każdej innej strony.

Wzór na równanie prostej:
y - y1 = [(y2 - y1)/(x2 - x1)](x - x1)

P-76655
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-02-22 11:26:42
Może to ja czegoś nie wiem, ale wyobraź sobie gre w której skaczesz, gdzie zmienia się prędkość spadania co jakiś czas o np. 0.2. Najpierw leci gracz posuwa się do góry (o coraz mniejszy mnożnik) a później w dół coraz szybciej. Wtedy może wlecieć w inny obiekt bez wykrycia kolizji. Hmm, może inaczej. Mamy powiedzmy spadający obiekt który jest dokładnie dokładnie o 0.8(~1)px oddalony (w osi Y) od górnej krawędzi tamtego innego obiektu. Mnożnik przesunięcia tego obiektu jest teraz 1.8. Nie jest teraz wykrywana kolizja, więc obiekt przesuwa się w dół znowu o 1.8 I co teraz? Kolizja nadal jest nie wykrywana ale obiekt jest teraz już nie na równo z górną krawędzią innego obiektu.
P-76701
unimator
» 2013-02-22 11:40:20
To sprawdź czy nastąpiła kolizja dla punktów po przesunięciu i dopiero wtedy przesuwaj. Czyli sprawdź czy nastąpi kolizja dla x+dx i jeśli nie nastąpiła to przesuń o dx.
P-76704
RazzorFlame
Temat założony przez niniejszego użytkownika
» 2013-02-22 15:30:37
Czaisz że to nic nie pomoże? Poprostu nie wykryje kolizji...

Edit:
Chyba że sprawdzałbym też czy kolizja nastąpiła w ten sposób ((int)ob.X + (int)ob.vX) itd
P-76711
Wasilek
» 2013-02-22 15:58:38
Powiedzmy, że lewa ściana ma współrzędną x=20
No i inny obiekt porusza się w prawo z prędkością 2.5. No i przykładowo ma aktualnie pozycję 19 - po obrocie pętli będzie miał 21.5. A więc sprawdzasz czy lewa ściana mieści się w przedziale od poprzedniej pozycji obiektu do teoretycznej pozycji obiektu po wykonaniu ruchu. Jeżeli nie zrozumiałeś to postaram się jakoś lepiej to wytłumaczyć (ogólnie przez chwilką na to wpadłem i użyje też to u siebie :P )
P-76714
« 1 » 2
  Strona 1 z 2 Następna strona