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

[Allegro] Problem z ustawieniem animacji

Ostatnio zmodyfikowano 2010-01-31 10:22
Autor Wiadomość
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 :

C/C++
#include <allegro.h>
class Cpostac
{
public:
    int x, y;
    short int kierunek, klatka;
};
Cpostac nija;
// Początek PROGRAMU !!!!!!!

volatile long speed = 0;
void increment_speed()
{
    speed++;
}
END_OF_FUNCTION( increment_speed );
LOCK_VARIABLE( speed );
LOCK_FUNCTION( increment_speed );
// OTWORZENIE GŁOWNEJ FUNKCJI = MAIN
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 );
   
   
   
    // Deklaracja bitmap
    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;
   
    // TWORZENIE BITMAP - Wgrywanie obrazków
    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 );
   
    //ziom
   
   
    nija1 = load_bmp( "nynja.bmp", default_palette );
   
   
   
   
    // kloc
    Kloc1 = load_bmp( "Kloc.bmp", default_palette );
   
    // HUD
    hud2 = load_bmp( "hud2.bmp", default_palette );
   
    //most
    most = load_bmp( "most.bmp", default_palette );
   
    // Klocek
    Kloc2 = load_bmp( "Kloc2.bmp", default_palette );
   
   
    // Tabliczka
    znak = load_bmp( "znak.bmp", default_palette );
   
    // Monety
    monet = load_bmp( "monet.bmp", default_palette );
   
    monet2 = load_bmp( "monet.bmp", default_palette );
    //Krzew
    krzew = load_bmp( "krzew.bmp", default_palette );
   
    // TWORZENIE DŹWIĘKU
    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;
    }
    // Ustalanie początkowej pozycji ludzika
   
   
    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;
    // Pętla odpowiedzialna za przemieszczanie zioma     
   
    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 ) );
        // Sterowanie animacją
        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 );
       
    }
    // USUWANIE BITMAP, KOŃCZENIE PROGRAMU
    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 ]
P-13209
pixelmaster
» 2010-01-22 16:01:03
Czy pojedyncza klatka z ludzikiem (w bitmapie) ma wymiary 60x60 ?
P-13210
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 :<
P-13212
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.
P-13230
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...
P-13367
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 ;)
P-13368
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

C/C++
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;
    // ładowanie grafik
    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 );
    // Ładowanie postaci
    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 )
        {
            // Poruszanie ludek1
            if( key[ KEY_LEFT ] ) ludek1.x--;
           
            if( key[ KEY_RIGHT ] ) ludek1.x++;
           
            if( key[ KEY_UP ] ) ludek1.y--;
           
            if( key[ KEY_DOWN ] ) ludek1.y++;
            // Poruszanie ludek2
            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 ) );
        //Wyświetlanie ludków
        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 ); //MAPA-GAME MODE
        /* Wyswietlanie napisu jeśli kolizja
        if( kolizja( ludek1.x,ludek1.y,ludek1.s, ludek1.w, ludek2.x, ludek2.y, ludek2.s, ludek2.w)==true)
        {masked_blit( ziom, bufor, 0,0, 300,100, ziom->w, ziom->h); }
       
        blit( bufor, screen, 0,0,0,0, 640,480);
        }     */
        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)' "
P-13413
malan
» 2010-01-31 01:09:28
Mogłeś podać następny błąd to by przyspieszyło sprawę:
C/C++
if( getpixel( bufor, 300, 100 ) == makecol( 255, 255, 255 ) )
{
    kolizja = 0; // ! ??? ! // nazwa zmiennej nie może być taka sama jak nazwa funkcji
    fixme_x = 300;
    fixme_y = 100;
}
P-13420
« 1 » 2
  Strona 1 z 2 Następna strona