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

[Allegro 4.4.2] Problem z animacją sprite'a w poziomie

Ostatnio zmodyfikowano 2015-10-11 21:32
Autor Wiadomość
Kubissus
Temat założony przez niniejszego użytkownika
[Allegro 4.4.2] Problem z animacją sprite'a w poziomie
» 2015-10-10 15:01:43
Witam! Podążam za pewnym poradnikiem Allegro 4.4.2 z YouTube (CodingMadeEasy). Autor poradników używa tablic itd. do przechowywania pozycji gracza itp. co mi się za bardzo nie podoba więc starałem się pisać wszystko obiektowo. Niestety moje "dzieło" nie działa poprawnie, ponieważ sprite nie animuje się w poziomie. (góra - dół działa). Kombinowałem z kodem i szukałem co jest nie tak ale bez rezultatów. Pomocy!

PS. Wiem, że ten konstruktor trochę kiepski jest :P

Oto kod:

C/C++
#include <allegro.h>
#include <stdlib.h>

#define ScreenWidth 800
#define ScreenHeight 600

////////////////////////////////////////////
//       //
// NIE ANIMUJE SIE W POZIOMIE :(     //
//                                        //
////////////////////////////////////////////

volatile long timer = 0;
void Increment()
{
    timer++;
}
END_OF_FUNCTION( Increment );

volatile bool closeWindow = false;
void CloseButtonCallBack()
{
    closeWindow = true;
}
END_OF_FUNCTION( CloseButtonCallBack );

class Gracz
{
    int speed;
    int x;
    int y;
   
    BITMAP * sprite;
   
    enum Source
    {
        Down,
        Left,
        Right,
        Up
    };
   
    int currentFrame[ 2 ]; // aktualna klatka w cyklu
    int Frames[ 2 ]; // ile klatek w górę i bok
    int Dimensions[ 2 ]; // oblicza wymiary klatek
   
    int switchFrame = 8; // odstęp pomiędzy klatkami
    int frameCounter = 0;
   
   
   
public:
   
    void DimSet()
    {
        Dimensions[ 0 ] = sprite->w / Frames[ 0 ];
        Dimensions[ 1 ] = sprite->h / Frames[ 1 ];
    }
   
    Gracz( int x1 = ScreenWidth / 2, int y1 = ScreenHeight / 2, int s = 2, BITMAP * spr = load_bitmap( "Sprites/char_player.pcx", NULL ), int cF1 = 0, int fr1 = 4, int fr2 = 4, int sF = 8, int fC = 0 )
    {
        speed = s;
        x = x1;
        y = y1;
        sprite = spr;
        currentFrame[ 0 ] = cF1;
        currentFrame[ 1 ] = Down;
        Frames[ 0 ] = fr1;
        Frames[ 1 ] = fr2;
        switchFrame = sF;
        frameCounter = fC;
       
        DimSet();
       
    }
   
   
    void Ruch()
    {
        if( key[ KEY_RIGHT ] )
        {
            x += speed;
            currentFrame[ 1 ] = Right;
        }
        else if( key[ KEY_LEFT ] )
        {
            x -= speed;
            currentFrame[ 1 ] = Left;
        }
        if( key[ KEY_UP ] )
        {
            y -= speed;
            currentFrame[ 1 ] = Up;
        }
        else if( key[ KEY_DOWN ] )
        {
            y += speed;
            currentFrame[ 1 ] = Down;
        }
        else
             isActive = false;
       
    }
   
    void Rysuj( BITMAP * B )
    {
        //draw_sprite(B, sprite, x, y);
       
        masked_blit( sprite, B, currentFrame[ 0 ], currentFrame[ 1 ] * Dimensions[ 1 ], x, y, Dimensions[ 0 ], Dimensions[ 1 ] );
    }
   
    void Kontrola()
    {
        if( !sprite )
        {
            textout_ex( screen, font, "ERROR", 400, 230, makecol( 255, 255, 254 ), - 1 );
            rest( 2000 );
            exit( 1 );
        }
    }
   
    void destroySprite()
    {
        destroy_bitmap( sprite );
    }
   
    void animacja()
    {
        if( isActive )
        {
            frameCounter += 1;
            if( frameCounter >= switchFrame )
            {
                currentFrame[ 0 ] += Dimensions[ 0 ];
                frameCounter = 0;
            }
            if( currentFrame[ 0 ] >= sprite->w )
                 currentFrame[ 0 ] = 0;
           
        }
        else
        {
            currentFrame[ 0 ] = 0;
            frameCounter = 0;
        }
       
    }
    bool isActive;
   
   
};


int main()
{
    allegro_init();
    install_keyboard();
    install_timer();
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, ScreenWidth, ScreenHeight, 0, 0 );
    set_window_title( "Sprite" );
   
    LOCK_FUNCTION( Increment );
    LOCK_VARIABLE( counter );
   
    LOCK_FUNCTION( CloseButtonCallBack );
    LOCK_VARIABLE( closeWindow );
   
    install_int_ex( Increment, BPS_TO_TIMER( 60 ) );
    set_close_button_callback( CloseButtonCallBack );
   
    BITMAP * Buffer = create_bitmap( ScreenWidth, ScreenHeight );
   
    Gracz g1;
   
    //BITMAP * sprite = load_bitmap("Sprites/char_player.pcx", NULL);
   
    g1.Kontrola();
   
   
    while( !closeWindow )
    {
        while( timer > 0 )
        {
            if( key[ KEY_ESC ] )
                 closeWindow = true;
           
            g1.isActive = true;
           
            g1.Ruch();
           
            g1.animacja();
           
            timer--;
        }
       
        rectfill( Buffer, 0, 0, ScreenWidth, ScreenHeight, makecol( 255, 255, 255 ) );
        g1.Rysuj( Buffer );
        blit( Buffer, screen, 0, 0, 0, 0, ScreenWidth, ScreenHeight );
        clear_bitmap( Buffer );
    }
   
    destroy_bitmap( Buffer );
    g1.destroySprite();
    allegro_exit();
    return 0;
}
END_OF_MAIN()

Sprite w formacie pcx: http://www.speedyshare.com/BaSK5/char-player.pcx

Z góry dziękuję za pomoc.
P-138353
Lora
» 2015-10-11 18:50:43
C/C++
if( key[ KEY_RIGHT ] )
{
    x += speed;
    currentFrame[ 1 ] = Right;
}
else if( key[ KEY_LEFT ] )
{
    x -= speed;
    currentFrame[ 1 ] = Left;
}
if( key[ KEY_UP ] )
{
    y -= speed;
    currentFrame[ 1 ] = Up;
}
else if( key[ KEY_DOWN ] )
{
    y += speed;
    currentFrame[ 1 ] = Down;
}
else
     isActive = false;

Z tego kodu wynika, że jeśli nie jest wciśnięty klawisz w górę albo w dół to zmienna isActive zawsze będzie false, a wtedy animacja nie będzie działać.
P-138439
Kubissus
Temat założony przez niniejszego użytkownika
» 2015-10-11 21:32:00
Jejku, dzięki wielkie :D Powinienem to od razu zauważyć.
P-138453
« 1 »
  Strona 1 z 1