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 class Cbullet { public: float x, y, w, h; float speed; int vx, vy; double size, cx, cy; int buf; bool alive; Cbullet(); }; klasa wroga class Cenemy { public: float x, y, w, h; float angle; int life; bool isAlive; int vx, vy; double size, cx, cy; int speed; Cenemy(); }; funkcja wykrywania kolizji 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 vector < Cenemy > enemy( 50 ); vector < Cbullet > bullet( 50 );
Oraz w końcu sprawdzanie kolizji w grze (formatowanie tekstu trochę padło) for( int i = 0; i < enemy.size(); i++ ) { 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; } else { } }
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ć? |
|
DejaVu |
» 2010-05-08 15:32:30 1) Użyj googli - ten algorytm milion razy już poprawiałem na forum. |
|
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: for( int i = 0; i < enemy.size(); i++ ) { 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; } else { } }
|
|
DejaVu |
» 2010-05-08 19:18:01 Poszukaj na forum poprawionej wersji algorytmu do wykrywania kolizji. Ten z kursu easykodera jest niepoprawny. |
|
Neomex0 Temat założony przez niniejszego użytkownika |
» 2010-05-08 20:27:30 Chodzi pewnie o ten kod? : 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: for( int i = 0; i < enemy.size(); i++ ) { 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; } else { } }
|
|
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: gdzie: vMove - wektor ruchu vDistance - wektor odległości od drugiego obiektu (liczony od środka obiektu [jednego i drugiego] z poprzedniej klatki) |
|
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: for( int i = 0; i < enemy.size(); i++ ) { for( int j = 0; j < bullet.size(); j++ ) { 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() ); } else { } } }
|
|
« 1 » |