paczaja Temat założony przez niniejszego użytkownika |
[Allegro, C++] Błąd po kolizji » 2009-03-27 17:17:35 Witam! Mam problem z moją grą w Allegro...jest to banalna gra, w którym jedna postać goni drugą i musi ją złapać...gdy złapie jest kolizja...i tu jest problem...funkcje kolizjii już mam, ale daje if'a, że jeżeli wystąpi kolizja ma pokazać jakiś obrazeczek a potem wrzucić ludki do rogów...wszystko by było dobrze, ale jeżeli złapiemy drugiego ludka i przytrzymamy np: strzałkę w górę to nasza postać zacznie w połowie ekranu...jak temu zaradzić?? Oto kod: class Cpostac { public: short int x, y; short int s, w; };
bool kolizja( int x1, int y1, int s1, int w1, int x2, int y2, int s2, int w2 ) { if( x2 <= x1 + s1 && x2 > x1 && y2 >= y1 && y2 <= y1 + w1 ) return true; else if( x2 <= x1 + s1 && x2 > x1 && y2 + w2 >= y1 && y2 + w2 <= y1 + w1 ) return true; else if( x2 + s2 <= x1 + s1 && x2 + s2 > x1 && y2 >= y1 && y2 <= y1 + w1 ) return true; else if( x2 + s2 <= x1 + s1 && x2 + s2 > x1 && y2 + w2 >= y1 && y2 + w2 <= y1 + w1 ) return true; else return false; };
Cpostac ludek1, ludek2; #include <allegro.h> #include <winalleg.h> #include <winable.h> volatile long speed = 0;
void increment_speed() { speed++; } END_OF_FUNCTION( increment_speed );
LOCK_VARIABLE( speed ); LOCK_FUNCTION( increment_speed );
int main() { allegro_init(); install_keyboard(); set_color_depth( 16 ); set_gfx_mode( GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0 ); clear_to_color( screen, makecol( 150, 150, 150 ) ); install_timer(); install_int_ex( increment_speed, BPS_TO_TIMER( 300 ) ); BITMAP * zacz = NULL; BITMAP * zlap = NULL; BITMAP * bufor = NULL; BITMAP * ludekb1 = NULL; BITMAP * ludekb2 = NULL; bufor = create_bitmap( 640, 480 ); ludekb1 = load_bmp( "ludekb1.bmp", default_palette ); ludekb2 = load_bmp( "ludekb2.bmp", default_palette ); zlap = load_bmp( "zlap.bmp", default_palette ); zacz = load_bmp( "zacz.bmp", default_palette ); ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40; ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40; while( !key[ KEY_SPACE ] ) { masked_blit( zacz, screen, 0, 0, 0, 0, zacz->w, zacz->h ); if( key[ KEY_ESC ] ) { destroy_bitmap( bufor ); destroy_bitmap( ludekb1 ); destroy_bitmap( ludekb2 ); allegro_exit(); return 0; } readkey(); } while( !key[ KEY_ESC ] ) { while( speed > 0 ) { if( ludek1.y == 440 ) ludek1.y--; if( ludek1.x == 610 ) ludek1.x--; if( ludek1.y == 0 ) ludek1.y++; if( ludek1.x == 0 ) ludek1.x++; if( key[ KEY_LEFT ] ) ludek1.x--; if( key[ KEY_RIGHT ] ) ludek1.x++; if( key[ KEY_UP ] ) ludek1.y--; if( key[ KEY_DOWN ] ) ludek1.y++; if( ludek2.y == 440 ) ludek2.y--; if( ludek2.x == 610 ) ludek2.x--; if( ludek2.y == 0 ) ludek2.y++; if( ludek2.x == 0 ) ludek2.x++; if( key[ KEY_A ] ) ludek2.x--; if( key[ KEY_D ] ) ludek2.x++; if( key[ KEY_W ] ) ludek2.y--; if( key[ KEY_S ] ) ludek2.y++; speed--; } clear_to_color( bufor, makecol( 150, 150, 150 ) ); masked_blit( ludekb1, bufor, 0, 0, ludek1.x, ludek1.y, ludek1.s, ludek1.w ); masked_blit( ludekb2, bufor, 0, 0, ludek2.x, ludek2.y, ludek2.s, ludek2.w ); if( kolizja( ludek1.x, ludek1.y, ludek1.s, ludek1.w, ludek2.x, ludek2.y, ludek2.s, ludek2.w ) == true ) { masked_blit( zlap, screen, 0, 0, 200, 200, zlap->w, zlap->h ); ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40; ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40; } blit( bufor, screen, 0, 0, 0, 0, 640, 480 ); } destroy_bitmap( bufor ); destroy_bitmap( ludekb1 ); destroy_bitmap( ludekb2 ); allegro_exit(); return 0; } END_OF_MAIN(); |
|
DejaVu |
» 2009-03-27 17:33:17 Proponuję zacząć od zmiany funkcji kolizji: http://archiwum.ddt.pl/?TextId=1660Ta z tematu jest przetestowana, natomiast z tego co forum pokazało, to z tą funkcją Easykodera są jakieś problemy. Po drugie polecam opisać problem lepiej/jaśniej, ponieważ czytając to 3 razy nie za bardzo wiem o co chodzi... przypuszczam, że może chodzić o to, iż ludek zostaje na środku, a nie w rogu (tak zrozumiałem). |
|
paczaja Temat założony przez niniejszego użytkownika |
» 2009-03-27 19:48:07 Z tą funkcją kolizji to narazie nie mam problemu...a co do tego błędu... if( kolizja( ludek1.x, ludek1.y, ludek1.s, ludek1.w, ludek2.x, ludek2.y, ludek2.s, ludek2.w ) == true ) { masked_blit( zlap, screen, 0, 0, 200, 200, zlap->w, zlap->h ); rest( 1000 ); ludek1.x = 610; ludek1.y = 440; ludek1.s = 40; ludek1.w = 40; ludek2.x = 0; ludek2.y = 0; ludek2.s = 40; ludek2.w = 40; } Teoretycznie gdy program wykryje błąd powinien pokazać obrazek ("zlap.bmp"), później odczekać 1s i wrzucić oba ludziki do rogów...i tak się dzieje, jeżeli odrazu po pokazaniu się w/w obrazka puścimy klawisze sterowania. W przeciwnym wypadku(jeżeli przytrzymamy klawisze sterowania) ludzik nie zaczyna już od rogu tylko w innym położeniu. Przesunie się zgodnie z użytym klawiszem(jeżeli użyjemy klawisza odpowiedzialnego za ruch w lewo to zacznie troche bardziej z lewej strony). To wygląda, jakby przez daną sekundę zbierał informacje o wciśniętym klawiszu, a następnie wyzwalał to, dzięki czemu nie zaczyna już w swoim oryginalnym położeniu. |
|
DejaVu |
» 2009-03-27 20:17:59 Jeśli nastąpi kolizja ustaw jeszcze speed = 0;. |
|
paczaja Temat założony przez niniejszego użytkownika |
» 2009-03-27 20:35:51 Super, działa. Dzięki. Mam jeszcze jedno pytanie: jak zrobić aby na początku nad player'em 1 pisało coś w stylu "gonisz!" a gdy już złapie to nad playerem nr2 by się takie coś pojawiało. Chodzi o to aby było tak na zmianę. Myślałem nad podwojeniem tej głównej pętli. Najpierw gra pracowałaby na 1 pętli, a jeżeli nastąpi kolizja to zmienia obrazek(na jakiś specyficzny - "goniący") i przechodzi na drugą pętlę...Ale może jest jakiś lepszy sposób? |
|
DejaVu |
» 2009-03-27 20:59:16 Jest... wstawiasz zmienną: int goniGracz = 0; Zmiana goniącego: switch( goniGracz ) { case 0: goniGracz = 1; break; case 1: goniGracz = 0; break; }
Sposobów jest dużo więcej i są też dużo krótsze, jednak to chyba będzie najprostsze do zrozumienia :). |
|
pekfos |
» 2009-03-28 09:01:31 po co sie trucdzić z tyloma argumentami? bool kolizja( int, int, int, int, int, int, int, int ); można to zrobić tak: bool kolizja( Cpostac, Cpostac ); bo w klasie Cpostac są zmienne x, y, h, w, więc zamiast podawać je osobno można podać je razem i oszczędzić sobie trudu |
|
DeBugger |
» 2009-03-29 16:18:40 bool kolizja( CPostac & postac, CPostac & postac1 ) |
|
« 1 » |