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

Kolizja działa nie do końca poprawnie :)

Ostatnio zmodyfikowano 2010-05-08 22:15
Autor Wiadomość
Neomex0
Temat założony przez niniejszego użytkownika
Kolizja działa nie do końca poprawnie :)
» 2010-05-08 14:55:39
Witam.
Kolizja niby działa, ponieważ po jakimś czasie strzelania we wroga, on ginie, ale nie za pierwszym razem.

klasa pocisku
C/C++
class Cbullet
{
public:
   
    float x, y, w, h;
   
    float speed;
   
    int vx, vy;
    double size, cx, cy;
   
    int buf;
   
    bool alive;
   
    Cbullet();
};
klasa wroga
C/C++
class Cenemy
{
public:
   
    float x, y, w, h;
    float angle;
   
    int life;
    bool isAlive;
   
   
   
    int vx, vy;
    double size, cx, cy;
    int speed;
   
    Cenemy();
    //void Move();
    //void Rotate();
    //void CountRotate();
};
funkcja wykrywania kolizji
C/C++
bool isCollision( int x1, int y1, int a1, int b1, int x2, int y2, int a2, int b2 )
{
    if(( x2 <= x1 + a1 && x2 > x1 && y2 >= y1 && y2 <= y1 + b1 ) ||
    ( x2 <= x1 + a1 && x2 > x1 && y2 + b2 >= y1 && y2 + b2 <= y1 + b1 ) ||
    ( x2 + a2 <= x1 + a1 && x2 + a2 > x1 && y2 >= y1 && y2 <= y1 + b1 ) ||
    ( x2 + a2 <= x1 + a1 && x2 + a2 > x1 && y2 + b2 >= y1 && y2 + b2 <= y1 + b1 ) )
    {
        return true;
    } else return false;
   
};
deklaracje klas
C/C++
vector < Cenemy > enemy( 50 );
vector < Cbullet > bullet( 50 );
Oraz w końcu sprawdzanie kolizji w grze (formatowanie tekstu trochę padło)
C/C++
//check collisions (enemy - bullet)
for( int i = 0; i < enemy.size(); i++ )
{ //x
   
    if( isCollision( bullet[ i ].x, bullet[ i ].y, bullet[ i ].w, bullet[ i ].h,
    enemy[ i ].x, enemy[ i ].y, enemy[ i ].w, enemy[ i ].h )
    == true )
    {
       
        enemy[ i ].isAlive = false;
        bullet[ i ].x = - 1000;
        bullet[ i ].y = - 1000;
        player.score += 5;
        player.killed_zombies += 1;
       
        //player.life-=0.01;     
    } else
    {
        //enemy[i].isAlive = true;
    }
   
} //x
Za wszelką pomoc będę dozgonnie wdzięczny :-)
---
PS
Z tego co widzę, to chyba poprostu kolizja zachodzi tylko w tedy gdy pocisk o id i zderza się z wrogiem o takim samym id.
Ale jak to naprawić?
P-16703
DejaVu
» 2010-05-08 15:32:30
1) Użyj googli - ten algorytm milion razy już poprawiałem na forum.
P-16704
Neomex0
Temat założony przez niniejszego użytkownika
» 2010-05-08 15:55:44
Mógłbyś mnie chociaż naprowadzić co jest nie tak?

Coś źle jest najprawdopodobniej tutaj:
C/C++
//check collisions (enemy - bullet)
for( int i = 0; i < enemy.size(); i++ )
{ //x
   
    if( isCollision( bullet[ i ].x, bullet[ i ].y, bullet[ i ].w, bullet[ i ].h,
    enemy[ i ].x, enemy[ i ].y, enemy[ i ].w, enemy[ i ].h )
    == true )
    {
       
        enemy[ i ].isAlive = false;
        bullet[ i ].x = - 1000;
        bullet[ i ].y = - 1000;
        player.score += 5;
        player.killed_zombies += 1;
       
        //player.life-=0.01;     
    } else
    {
        //enemy[i].isAlive = true;
    }
   
} //x
P-16705
DejaVu
» 2010-05-08 19:18:01
Poszukaj na forum poprawionej wersji algorytmu do wykrywania kolizji. Ten z kursu easykodera jest niepoprawny.
P-16712
Neomex0
Temat założony przez niniejszego użytkownika
» 2010-05-08 20:27:30
Chodzi pewnie o ten kod? :
C/C++
bool isCollision( float x1, float y1, float s1, float w1, float x2, float y2, float s2, float w2 )
{
    if( x1 + s1 >= x2 && x1 <= x2 + s2 && y1 + w1 >= y2 && y1 <= y2 + w2 ) return( true );
   
    return( false );
};

Zmieniłem, może faktycznie częściej wykrywa kolizje, ale wciąż nie za każdym razem, problem jest chyba w obiegu pętli, jeszcze raz zarzuce kod:

C/C++
//check collisions (enemy - bullet)
for( int i = 0; i < enemy.size(); i++ )
{ //x
   
    if( isCollision( bullet[ i ].x, bullet[ i ].y, bullet[ i ].w, bullet[ i ].h, enemy[ i ].x, enemy[ i ].y, enemy[ i ].w, enemy[ i ].h ) == true )
    {
       
        enemy[ i ].isAlive = false;
        bullet[ i ].x = - 1000;
        bullet[ i ].y = - 1000;
        player.score += 5;
        player.killed_zombies += 1;
       
        //player.life-=0.01;     
    } else
    {
        //enemy[i].isAlive = true;
    }
   
} //x
P-16716
michalp
» 2010-05-08 22:07:06
Ten sposób wykrywania kolizji nie jest najlepszy. A mówiąc wprost: beznadziejny (przynajmniej w tym przypadku). Dlaczego? Nie bierze on pod uwagę przesunięcia obiektu. Tzn. obiekt jest po jednej stronie obiektu a w następnej klatce po przeciwnej i kolizja nie zostaje wykryta. Zaprojektuj sobie (lub skorzystaj z gotowego pomysłu), który uwzględnia ten problem. Jednym z takich pomysłów jest metoda SAT.

Innym sposobem jest przesunięcie (a w zasadzie dodanie) wszystkich wierzchołków o wektor przesunięcia co utworzy nowy obiekt. I to go bierz pod uwagę przy sprawdzaniu kolizji. Tyle, że będziesz musiał wyznaczyć wektor o jaki trzeba przesunąć obiekt by już nie kolidował (nie miał wspólnej części z innym obiektem/obiektami) i był jak najbliżej położenia z poprzedniej klatki. To (jeśli się nie mylę) da się obliczyć ze wzoru:

vMove - |vDistance|
gdzie:

vMove - wektor ruchu
vDistance - wektor odległości od drugiego obiektu (liczony od środka obiektu [jednego i drugiego] z poprzedniej klatki)
P-16721
Neomex0
Temat założony przez niniejszego użytkownika
» 2010-05-08 22:15:47
Na szczęście udało mi się rozwiązać problem.
Jak podkreślałem problemem była budowa petli for, taka jest poprawna:
C/C++
for( int i = 0; i < enemy.size(); i++ )
{ //x
   
    for( int j = 0; j < bullet.size(); j++ )
    { //x2
       
        if( isCollision( bullet[ j ].x, bullet[ j ].y, bullet[ j ].w, bullet[ j ].h,
        enemy[ i ].x, enemy[ i ].y, enemy[ i ].w, enemy[ i ].h )
        == true )
        {
           
            enemy[ i ].isAlive = false;
            bullet[ j ].x = - 10000;
            bullet[ j ].y = - 10000;
            player.score += 5;
            player.killed_zombies += 1;
            enemy.push_back( Cenemy() );
            //player.life-=0.01;     
        } else
        {
            //enemy[i].isAlive = true;
        }
       
    } //x2
} //x
P-16722
« 1 »
  Strona 1 z 1