Qtk Temat założony przez niniejszego użytkownika |
[Allegro] Problem z ustawieniem animacji » 2010-01-22 15:49:39 Witam, wcześniejszy problem został już dawno rozwiązany, z pomocą malana ;]. Kolizji jak na razie nie rozumiem wcale, więc wziąłem się za animacje, wszystko ładnie się kompiluje, lecz gdy włączam grę, że tak powiem, bitmapy zaczynają wariować :P http://img16.imageshack.us/img16/5709/bladyb.jpg. Pomoże mi ktoś z tym problemem? Kod źródłowy : #include <allegro.h> class Cpostac { public: int x, y; short int kierunek, klatka; }; Cpostac nija;
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( 32 ); set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 ); install_timer(); install_int_ex( increment_speed, BPS_TO_TIMER( 100 ) ); clear_to_color( screen, makecol( 128, 128, 128 ) ); install_sound( DIGI_AUTODETECT, MIDI_AUTODETECT, "" ); set_volume( 255, 255 ); BITMAP * bufor = NULL; BITMAP * tlo = NULL; BITMAP * nija1 = NULL; BITMAP * Kloc1 = NULL; BITMAP * hud2 = NULL; BITMAP * most = NULL; BITMAP * Kloc2 = NULL; BITMAP * znak = NULL; BITMAP * monet = NULL; BITMAP * monet2 = NULL; BITMAP * krzew = NULL; SAMPLE * dzwiek = NULL; bufor = create_bitmap( 800, 600 ); if( !bufor ) { set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 ); allegro_message( "Nie mogę utworzyć bufora !" ); allegro_exit(); return 0; } tlo = load_bmp( "tlo.bmp", default_palette ); nija1 = load_bmp( "nynja.bmp", default_palette ); Kloc1 = load_bmp( "Kloc.bmp", default_palette ); hud2 = load_bmp( "hud2.bmp", default_palette ); most = load_bmp( "most.bmp", default_palette ); Kloc2 = load_bmp( "Kloc2.bmp", default_palette ); znak = load_bmp( "znak.bmp", default_palette ); monet = load_bmp( "monet.bmp", default_palette ); monet2 = load_bmp( "monet.bmp", default_palette ); krzew = load_bmp( "krzew.bmp", default_palette ); dzwiek = load_sample( "muse.wav" ); if( !dzwiek ) { set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 ); allegro_message( "nie mogę załadować dzwieku !" ); allegro_exit(); return 0; } int Kloc1_x = 50, Kloc1_y = 250; int hud2_x = 55, hud2_y = 0, hud2_s = 100, hud2_w = 40; int most_x = 245, most_y = 470; int Kloc2_x = 317, Kloc2_y = 465; int znak_x = 100, znak_y = 200; int monet_x = 500, monet_y = 100; int monet2_x = 100, monet2_y = 100; int krzew_x = 200, krzew_y = 100; play_sample( dzwiek, 255, 127, 1000, 1 ); int frame = 0; nija.x = 100; nija.y = 100; nija.klatka = 0; nija.kierunek = 0; while( !key[ KEY_ESC ] ) { clear_to_color( bufor, makecol( 150, 150, 150 ) ); rest( 10 ); while( speed > 0 ) { if( key[ KEY_LEFT ] ) { nija.kierunek = 4; nija.x -= 2; } if( key[ KEY_RIGHT ] ) { nija.kierunek = 2; nija.x += 2; } if( key[ KEY_UP ] ) { nija.kierunek = 1; nija.y -= 2; } if( key[ KEY_DOWN ] ) { nija.kierunek = 3; nija.y += 2; } speed--; frame++; if( frame > 80 ) frame = 0; } if( key[ KEY_A ] ) { adjust_sample( dzwiek, 255, 127, 500, 1 ); } if( key[ KEY_S ] ) { adjust_sample( dzwiek, 255, 127, 2000, 1 ); } if( key[ KEY_D ] ) { adjust_sample( dzwiek, 255, 0, 1000, 1 ); } if( key[ KEY_F ] ) { adjust_sample( dzwiek, 255, 255, 1000, 1 ); } clear_to_color( bufor, makecol( 150, 150, 150 ) ); if( frame < 20 ) { nija.klatka = 0; } else if( frame >= 20 && frame < 40 ) { nija.klatka = 1; } blit( tlo, bufor, 0, 0, 0, 0, 800, 600 ); masked_blit( nija1, bufor, nija.kierunek * 60, nija.klatka * 60, nija.x, nija.y, 60, 60 ); masked_blit( Kloc1, bufor, 0, 0, Kloc1_x, Kloc1_y, Kloc1->w, Kloc1->h ); masked_blit( hud2, bufor, 0, 0, hud2_x, hud2_y, hud2->w, hud2->h ); masked_blit( most, bufor, 0, 0, most_x, most_y, most->w, most->h ); masked_blit( Kloc2, bufor, 0, 0, Kloc2_x, Kloc2_y, Kloc2->w, Kloc2->h ); masked_blit( znak, bufor, 0, 0, znak_x, znak_y, znak->w, znak->h ); masked_blit( monet, bufor, 0, 0, monet_x, monet_y, monet->w, monet->h ); masked_blit( monet2, bufor, 0, 0, monet2_x, monet2_y, monet2->w, monet2->h ); masked_blit( krzew, bufor, 0, 0, krzew_x, krzew_y, krzew->w, krzew->h ); blit( bufor, screen, 0, 0, 0, 0, 800, 600 ); } readkey(); remove_int( increment_speed ); stop_sample( dzwiek ); destroy_bitmap( Kloc1 ); destroy_bitmap( hud2 ); destroy_bitmap( bufor ); destroy_bitmap( Kloc2 ); destroy_bitmap( znak ); destroy_bitmap( monet ); destroy_bitmap( monet2 ); destroy_bitmap( krzew ); destroy_sample( dzwiek ); allegro_exit(); return 0; } END_OF_MAIN(); [ / code ] |
|
pixelmaster |
» 2010-01-22 16:01:03 Czy pojedyncza klatka z ludzikiem (w bitmapie) ma wymiary 60x60 ? |
|
Qtk Temat założony przez niniejszego użytkownika |
» 2010-01-22 16:15:08 Pojedyncza klatka (mam dwie oddzielnie i połączone w jedną ) ma wymiary 109 x 204 :<... Wymiary poszczególnych klatek mają jakieś znaczenie ?
Edit. Poprawiłem w kodzie wymiary,lecz nadal animacja sama się włącza i jest po prostu niedokładna :< |
|
malan |
» 2010-01-22 23:32:12 masked_blit( nija1, bufor, nija.kierunek * 60, nija.klatka * 60, nija.x, nija.y, 60, 60 ); Jeśli dobrze pamiętam, to trzeci ( nija.kierunek*60) i czwarty ( nija.kierunek*60) argument to są współrzędne (x i y) kawałka bitmapy, który chce się "wyciąć". Patrząc w kod nija.klatka jest zawsze równa 0 lub 1, czyli (jeśli dobrze kombinuję) bitmapa zawsze będzie Ci się wyświetlać w rozmiarach 60 x 60, bo 1*60=60. Ewentualnie kiedy nija.klatka == 0 to (po zmianie wymiarów (ostatnie dwa argumenty)) powinno się wyświetlić dobrze. Poprawcie mnie, jeśli coś pomieszałem. |
|
dmx81 |
» 2010-01-28 23:43:34 witam, czy dalej problem sie powtarza, czy juz naprawiony? jak malan napisal nija.klatka - to wsp. x, nija.kierunek - to wsp. y = sa to wspolrzedne, od ktorych beda rysowane twoje klatki, nastepnie podajesz miejsce, gdzie maja byc narysowane na buforze (ew. na screen), a nastepnie jest podana szerokosc i wysokosc rysowanego obiektu. w twoim przypadku, jesli np nija.kierunek=4 - program bedzie chcial rysowac twoja bitmape od y=4*60 - czyli y start to 240, y stop to 240+60 - jesli obrazek jest mniejszy, to bedzie tam poprostu puste pole, jesli obrazek jest wiekszy, bedzie to wlasnie ten wycinek bitmapy. wg zapisu jaki podales w kodzie: powinienes posiadac bitmape: szeroka na 60 + 60, wysoka na 4x60, czyli jakby tabela 2 kolumny i 4 wiersze, gdzie kazde okno tabeli to twoja klatka, jaka kolejno bedzie program wyswietlal. jesli twoj obrazek jest mniejszy, posiada tylko 2 klatki - jak widzisz, na ekranie zobaczysz wycinki swojego rysunku nalezy albo poprawic bitmape, albo poprawic w kodzie warunki przechodzenia z klatki do klatki, w wypadku 109x204 x 2 , powinno byc masked_blit( nija1, bufor, nija.kierunek*109 ,nija.klatka*204 ,nija.x, nija.y, 109,204); przy czym musisz pamietac, ze jesli zmieni sie u ciebie nija.klatka z 0 na 1, poczatkiem twojej wyswietlanej bitmapy bedzie 204 - czyli tak naprawde to, co masz pod obrazkiem, wiec nic, nic tez nie da wpisanie nija.klatka*polowa z 204 - wtedy wyswietli ci sie twoj obrazek - ale od polowy w dol czyli jesli masz tylko jeden "wiersz w kolumnie" w swojej bitmapie, zmienna nija.klatka powinna byc niezmienna, x za to mozesz zmieniac o 0 do 1 (dopoki masz przeznaczone do wyswietlania 2 klatki - 0 dla poczatku klatki do 109, 1 dla 109 do konca, czyli o kolejne 109) jesli masz za to 2 wiersze, a jedna kolumne (bo napisales, ze masz 2 polaczone w 1 ale nie wiem czy poziomo, czy pionowo) wtedy analogicznie - zmienic mozesz nija.klatka z 0 (gorna postac od o do 204) na 1 (od 204 do dolu - o nastepne 204) ale w tym przypadku x - musi pozostac 0, czyli nija.kierunek, narysowany bedzie od 0 do 109, jesli nija.kierunek bedzie 1 i wieksze, bedzie wskazywac poza pole obrazka - efekt=pusta klatka odp nr 2 : animacja sama sie wlacza: dlatego, ze jest ona zalezna od zmiennej frames - ktora jak widzisz, zmienia sie nieustannie, tak wiec i animacja postepuje za zmienna frames - w dodatku masz "pusty przebieg" przy frames >40 czyli jakies pol sek sie nic nie dzieje ;) mozesz to rozwiazac, przez np bool left_wcisniety==NULL; if(key[KEY_LEFT]) left_wcisniety=true; else left=false;
if((frames<20||frames>40&&frames<60)&&left_wcisniety==true) //kod...
ps. kod z glowy, nie wiem czy zadziala, chodzi o pomysl... |
|
dmx81 |
» 2010-01-28 23:59:09 a jesli chcialbys dowiedziec sie czegos o kolizji, mysle, ze w przejrzysty sposob moge cos napisac ;) ja kolizje rozpracowywalem na kartce w kratke, z paroma kwadracikami i sprawdzalem, kiedy zachodzi kolizja, czyli styk, lub przenikanie sie tych kwadracikow, dla kazdego zapisalem sobie x1,y1, x2,y2 - no i oczywiscie taki uklad wspolrzednych, gdzie gorny lewy rog kartki to 0,0, y w dol rosnie, x w prawo rosnie
pocwisz sobie, spisuj sobie na kartce mozliwosci jakie zachodza, np kwadracik nr 1 wchodzi w nr2 lewa scianka, aby byla kolizja, na pewno musza byc na tej samej wysokosci , na podobnych x - i spisujesz sobie, kiedy ta kolizja sie konczy, np kiedy dolna krawedz tego, co jest wyzej, juz sie nie styka z gorna tego, co ponizej
krawedz gorna - oznaczona jako y, dolna jako y+wysokosc
krawedz lewa jako x, prawa jako x+szerokosc
oznaczona jako = lezy na prostej ;) |
|
Qtk Temat założony przez niniejszego użytkownika |
» 2010-01-30 17:10:33 Dzięki za odpowiedź :P Zaraz przestudiuję Twój sposób na kartce, lecz najpierw muszę zadać kolejne pytanie, dotyczące kolizji, bo z animacją na razie dałem sobie spokój :P 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, ziom1; #include <allegro.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_WINDOWED, 640, 480, 0, 0 ); install_timer(); install_int_ex( increment_speed, BPS_TO_TIMER( 100 ) ); BITMAP * bufor = NULL; BITMAP * ludekb1 = NULL; BITMAP * ludekb2 = NULL; BITMAP * ziom = NULL; bufor = create_bitmap( 640, 480 ); ludekb1 = load_bmp( "ludekb1.bmp", default_palette ); ludekb2 = load_bmp( "ludekb2.bmp", default_palette ); ziom = load_bmp( "ziom.bmp", default_palette ); ludek1.x = 100; ludek1.y = 100; ludek1.s = 40; ludek1.w = 40; ludek2.x = 300; ludek2.y = 100; ludek2.s = 40; ludek2.w = 40; ziom1.x = 300; ziom1.y = 100; ziom1.s = 40; ziom1.w = 40; while( !key[ KEY_ESC ] ) { while( speed > 0 ) { 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( 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 ); blit( ziom, bufor, 0, 0, 300, 100, ziom->w, ziom->h ); blit( ziom, bufor, 0, 0, 300, 100, ziom->w, ziom->h ); if( getpixel( bufor, 300, 100 ) == makecol( 255, 255, 255 ) ) { kolizja = 0; fixme_x = 300; fixme_y = 100; } if( getpixel( bufor, wysw_hero_x1, wysw_hero_y1 ) != makecol( 255, 255, 255 ) ) { kolizja = 1; wysw_hero_x1 = fixme_x; wysw_hero_y1 = fixme_y; } masked_blit( ludekb2, bufor, 0, 0, ludek2.x, ludek2.y, ludek2.s, ludek2.w ); masked_blit( ludekb2, bufor, 0, 0, 0, 0, 1024, 768 ); destroy_bitmap( bufor ); destroy_bitmap( ludekb2 ); destroy_bitmap( ziom ); allegro_exit(); return 0; } END_OF_MAIN();
Może mi ktoś wytłumaczyć, co tu robię źle ??:< Dodam, że wyskakują mi tego typu błedy przy kompilacji : " assignment of function `bool kolizja(int, int, int, int, int, int, int, int)' " |
|
malan |
» 2010-01-31 01:09:28 Mogłeś podać następny błąd to by przyspieszyło sprawę: if( getpixel( bufor, 300, 100 ) == makecol( 255, 255, 255 ) ) { kolizja = 0; fixme_x = 300; fixme_y = 100; } |
|
« 1 » 2 |