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

[SFML] detekcja kolizji między okręgami

Ostatnio zmodyfikowano 2016-05-15 00:15
Autor Wiadomość
Jadranko
Temat założony przez niniejszego użytkownika
[SFML] detekcja kolizji między okręgami
» 2016-05-14 23:31:20
Cześć!

Tworzę grę a'la Haxball i mam problem z detekcją dwóch okręgów (piłkarza i piłki). Korzystam z twierdzenia pitagorasa i kolizja działa jeżeli piłkarz styka się z piłką w 0 stopniach, 90, 180, 270 oraz ich okolicach. Problem następuje, gdy piłkarz zbliża się do piłki pod kątem pośrednim czyli np 45, 135 itp... (jednocześnie wciskając np strzałkę w dół i w prawo). wtedy piłkarz wchodzi na piłkę i kolizje wariują.

C/C++
static void czyKolidujePilka( player & gracz, player & pilka, sf::Vector2f ruch ) {
    sf::Vector2f dist1 = gracz.srodekPilkarz();
    sf::Vector2f dist2 = pilka.srodekPilka();
    sf::Vector2f dist = gracz.srodekPilkarz() - pilka.srodekPilka();
   
    float rad1, rad2, rad;
    rad1 = gracz.promienPilkarz();
    rad2 = pilka.promienPilka();
    rad = rad1 + rad2;
   
    float d = sqrt( pow( dist1.x - dist2.x, 2 ) + pow( dist1.y - dist2.y, 2 ) );
   
    if( d < rad ) {
        if( ruch.x > 0 ) {
            pilka.ruchPilki( sf::Vector2f( ruch.x, 0 ) );
        } else if( ruch.x < 0 ) {
            pilka.ruchPilki( sf::Vector2f( ruch.x, 0 ) );
        } else if( ruch.y > 0 ) {
            pilka.ruchPilki( sf::Vector2f( 0, ruch.y ) );
        } else if( ruch.y < 0 ) {
            pilka.ruchPilki( sf::Vector2f( 0, ruch.y ) );
        }
    }
}

A druga sprawa, to poruszanie się piłkarza wraz z piłką. Nie mam pojęcia jak mogę zrobić poruszanie się piłki, bo ona porusza się wyłącznie pod kątami prostymi (0, 90, 180, 270).

P-148231
pekfos
» 2016-05-14 23:37:14
C/C++
if( ruch.x > 0 ) {
    pilka.ruchPilki( sf::Vector2f( ruch.x, 0 ) );
} else if( ruch.x < 0 ) {
    pilka.ruchPilki( sf::Vector2f( ruch.x, 0 ) );
} else if( ruch.y > 0 ) {
    pilka.ruchPilki( sf::Vector2f( 0, ruch.y ) );
} else if( ruch.y < 0 ) {
    pilka.ruchPilki( sf::Vector2f( 0, ruch.y ) );
}
Jaki to ma cel?
P-148232
Jadranko
Temat założony przez niniejszego użytkownika
» 2016-05-14 23:42:09
Ten fragment kodu odpowiada za poruszanie się piłki, jeżeli d < rad to w zależności od ruchu piłkarza piłka porusza się w tym samym kierunku. Jeżeli piłkarz biegnie w prawo to znaczy że x jest dodatni więc piłka też porusza się w tym samym kierunku.

Oto kod, w którym piłkarz koliduje ze ścianami, gdzie V to zbiór wszystkich ścian(białych linii):

C/C++
static void czyKoliduje( player & g1, std::vector < player > V, sf::Vector2f ruch ) {
    sf::FloatRect X = g1.doKolizjiPilkarz();
    sf::FloatRect Y = g1.doKolizjiPilkarz();
   
    X.left += ruch.x;
    Y.top += ruch.y;
    bool kolX = false; bool kolY = false;
   
    for( int i = 0; i < V.size(); i++ ) {
        if( i < V.size() ) {
            if( X.intersects( V[ i ].doKolizjiPrzeszkoda() ) )
                 kolX = true;
            else if( Y.intersects( V[ i ].doKolizjiPrzeszkoda() ) )
                 kolY = true;
           
        }
    }
   
    if( !kolX )
         g1.ruch( sf::Vector2f( ruch.x, 0 ) );
   
    if( !kolY )
         g1.ruch( sf::Vector2f( 0, ruch.y ) );
   
}
P-148234
pekfos
» 2016-05-14 23:46:06
Ale czemu nie pilka.ruchPilki(ruch)?
P-148235
Jadranko
Temat założony przez niniejszego użytkownika
» 2016-05-14 23:56:43
Racja, działa. Zrobiłem jeszcze kilka if'ów i już w miarę to wygląda, dzięki ;)
P-148236
Jadranko
Temat założony przez niniejszego użytkownika
» 2016-05-14 23:57:36
Jeszcze kwestia detekcji kolizji, czy jakoś można precyzyjniej je wykrywać między okręgami? Czy tylko można się opierać na tw. Pitagorasa?
P-148237
pekfos
» 2016-05-15 00:15:27
Można to robić efektywniej, operując na kwadracie odległości, a nie samej odległości. Pierwiastkowanie jest dość kosztowne, w porównaniu do mnożenia.
P-148238
« 1 »
  Strona 1 z 1