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

[Allegro] mario - wolne poruszanie

Ostatnio zmodyfikowano 2009-05-12 21:41
Autor Wiadomość
steckel
Temat założony przez niniejszego użytkownika
[Allegro] mario - wolne poruszanie
» 2009-05-02 09:18:03
Witam! Mam problem z grą Mario. Porusza się on bardzo wolno bez względu na szybkość.
Do liczenia okresów użyłem pętli:
C/C++
int czas = clock();
while( !key[ KEY_ESC ] ) {
    if( szybkosc != 0 && czas < clock() - 100 / szybkosc ) {
        przesu ń();
        czas = clock();
    }
}
A o to pełny kod:
C/C++
#include <allegro.h>
#include <ctime>
#include <string>
#include <iostream>

using namespace std;

const int PRZYSPIESZENIE = 5;
const int OPOZNIENIE = 2;
const int KOLOR_TLA = 0;
const int CZAS = 50;

class objekt {
protected:
    int mPozycjaX;
    int mPozycjaY;
    int mSzybkoscX;
    int mSzybkoscY;
    int mWysokosc;
    int mSzerokosc;
    int mBuforX;
    int mBuforY;
    int mCzasX;
    int mCzasY;
    BITMAP * mGrafika;
    BITMAP * mBufor;
public:
    objekt();
    objekt( int, int, int, int, int, int, BITMAP * );
    void wyswietl();
    void zwiekszSzybkoscX( int a ) { mSzybkoscX += a; }
    void aktualizuj();
    void zwolnijX( int );
    void zwiekszSzybkoscY( int a ) { mSzybkoscY += a; }
    void zwolnijY( int );
    bool kolizjaY();
    bool kolizjaX();
    void ustawCzasX() { mCzasX = clock(); }
    int pobierzCzasX() { return mCzasX; }
    void ustawCzasY() { mCzasY = clock(); }
    int pobierzCzasY() { return mCzasY; }
    int pobierzSzybkoscX();
    int pobierzSzybkoscY();
};

class gracz
    : public objekt
{
public:
};

void allegro();
void klawisz();
void init();
void aktualizacja();
void odswierz();
void wczytajPlansze( int );

gracz::objekt * player;

int ** plansza;

int main() {
    allegro();
    int poziom = 1;
    wczytajPlansze( poziom );
    //init();
    int czasKlawisz = clock();
    int czasAktualizacja = clock();
    int czasOdswierz = clock();
    while( !key[ KEY_ESC ] ) {
        if( czasKlawisz < clock() - CZAS ) {
            klawisz();
            czasKlawisz = clock();
        }
        if( czasOdswierz < clock() - CZAS ) {
            odswierz();
            czasOdswierz = clock();
        }
        if( czasAktualizacja < clock() - CZAS ) {
            player->aktualizuj();
            czasAktualizacja = clock();
        }
    }
    return 0;
}
END_OF_MAIN();

objekt::objekt() {
    mPozycjaX = 400;
    mPozycjaY = 300;
    mSzybkoscX = 0;
    mSzybkoscY = 0;
    mWysokosc = 50;
    mSzerokosc = 50;
    mCzasX = clock();
    mCzasY = clock();
    mBuforX = mPozycjaX;
    mBuforY = mPozycjaY;
    mGrafika = create_bitmap( mSzerokosc, mWysokosc );
    mBufor = create_bitmap( mSzerokosc, mWysokosc );
    clear_to_color( mBufor, KOLOR_TLA );
}

objekt::objekt( int pozX, int pozY, int szybX, int szybY, int szer, int wys, BITMAP * graf ) {
    mPozycjaX = pozX;
    mPozycjaY = pozY;
    mSzybkoscX = szybX;
    mSzybkoscY = szybY;
    mWysokosc = wys;
    mSzerokosc = szer;
    mCzasX = clock();
    mCzasY = clock();
    mBuforX = mPozycjaX;
    mBuforY = mPozycjaY;
    mGrafika = graf;
    mBufor = create_bitmap( mSzerokosc, mWysokosc );
    clear_to_color( mBufor, KOLOR_TLA );
}

void allegro() {
    allegro_init();
    install_keyboard();
    set_color_depth( 32 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 );
    set_palette( default_palette );
    clear_to_color( screen, KOLOR_TLA );
}

void objekt::wyswietl() {
    blit( mBufor, screen, 0, 0, mBuforX, mBuforY, mGrafika->w, mGrafika->h );
    masked_blit( mGrafika, screen, 0, 0, mPozycjaX, mPozycjaY, mGrafika->w, mGrafika->h );
    mBuforX = mPozycjaX;
    mBuforY = mPozycjaY;
}

void klawisz() {
    if( key[ KEY_RIGHT ] ) {
        player->zwiekszSzybkoscX( PRZYSPIESZENIE );
    }
    if( key[ KEY_LEFT ] ) {
        player->zwiekszSzybkoscX( - PRZYSPIESZENIE );
    }
    if( key[ KEY_UP ] ) {
        player->zwiekszSzybkoscY( PRZYSPIESZENIE );
    }
}

void objekt::aktualizuj() {
    if( mSzybkoscX != 0 && pobierzCzasX() < clock() -( 100 / pobierzSzybkoscX() ) ) {
        if( !kolizjaX() ) {
            if( mSzybkoscX > 0 )
                 mPozycjaX++;
            else
                 mPozycjaX--;
           
            ustawCzasX();
        }
        else {
            mSzybkoscX = 0;
        }
    }
    if( mSzybkoscY != 0 && pobierzCzasY() < clock() -( 100 / pobierzSzybkoscY() ) ) {
        if( !kolizjaY() ) {
            if( mSzybkoscY < 0 )
                 mPozycjaY++;
            else
                 mPozycjaY--;
           
            ustawCzasY();
        }
        else {
            mSzybkoscY = 0;
        }
    }
    /*if (pobierzCzasX<clock()-100){
        zwolnijX(OPOZNIENIE);
      }
      if (pobierzCzasX<
      mSzybkoscY-=OPOZNIENIE;*/
}

void odswierz() {
    player->wyswietl();
}

void objekt::zwolnijX( int a ) {
    if( mSzybkoscX > 0 ) {
        mSzybkoscX -= a;
        if( mSzybkoscX < 0 ) mSzybkoscX = 0;
       
    }
    else if( mSzybkoscX < 0 ) {
        mSzybkoscX += a;
        if( mSzybkoscX > 0 ) mSzybkoscX = 0;
       
    }
}

void objekt::zwolnijY( int a ) {
    if( mSzybkoscY > 0 ) {
        mSzybkoscY -= a;
        if( mSzybkoscY < 0 ) mSzybkoscY = 0;
       
    }
    else if( mSzybkoscY < 0 ) {
        mSzybkoscY += a;
        if( mSzybkoscY > 0 ) mSzybkoscY = 0;
       
    }
}

void wczytajPlansze( int poziom ) {
    plansza = new int *[ 800 ];
    for( int a = 0; a < 800; a++ ) plansza[ a ] = new int[ 600 ];
   
    string nazwaPlanszy = "plansze/plansza";
    nazwaPlanszy = nazwaPlanszy + char( poziom + 48 ) + ".bmp";
    //cout<<nazwaPlanszy;
    BITMAP * planszaPlik = load_bmp( nazwaPlanszy.c_str(), default_palette );
    for( int a = 0; a < 800; a++ ) for( int b = 0; b < 600; b++ ) {
        if( getpixel( planszaPlik, a, b ) == makecol( 255, 0, 0 ) ) {
            plansza[ a ][ b ] = 1;
        }
        else if( getpixel( planszaPlik, a, b ) == makecol( 255, 255, 0 ) ) {
            BITMAP * tym = load_bmp( "grafika/gracz.bmp", default_palette );
            player = new gracz::objekt( a, b, 0, 0, tym->w, tym->h, tym );
        }
        else {
            plansza[ a ][ b ] = 0;
        }
    }
    blit( planszaPlik, screen, 0, 0, 0, 0, 800, 600 );
}

bool objekt::kolizjaY() {
    if( mSzybkoscY < 0 ) {
        int tymY = mPozycjaY - mSzybkoscY + mWysokosc;
        if( tymY >= 600 || tymY <= 0 ) return true;
       
        for( int a = mPozycjaX; a < mPozycjaX + mSzerokosc; a++ ) {
            if( plansza[ a ][ tymY ] == 1 ) return true;
           
        }
        return false;
    }
    else if( mSzybkoscY > 0 ) {
        int tymY = mPozycjaY - mSzybkoscY;
        if( tymY >= 600 || tymY <= 0 ) return true;
       
        for( int a = mPozycjaX; a < mPozycjaX + mSzerokosc; a++ ) {
            if( plansza[ a ][ tymY ] == 1 ) return true;
           
        }
        return false;
    }
    return false;
}

bool objekt::kolizjaX() {
    if( mSzybkoscX > 0 ) {
        int tymX = mPozycjaX + mSzybkoscX + mSzerokosc;
        if( tymX >= 800 || tymX <= 0 ) return true;
       
        for( int a = mPozycjaY; a < mPozycjaY + mWysokosc; a++ ) {
            if( plansza[ tymX ][ a ] == 1 ) return true;
           
        }
        return false;
    }
    else if( mSzybkoscX < 0 ) {
        int tymX = mPozycjaX + mSzybkoscX;
        if( tymX >= 800 || tymX <= 0 ) return true;
       
        for( int a = mPozycjaY; a < mPozycjaY + mWysokosc; a++ ) {
            if( plansza[ tymX ][ a ] == 1 ) return true;
           
        }
        return false;
    }
    return false;
}

int objekt::pobierzSzybkoscX() {
    if( mSzybkoscX >= 0 ) return mSzybkoscX;
    else return - mSzybkoscX;
   
}

int objekt::pobierzSzybkoscY() {
    if( mSzybkoscY >= 0 ) return mSzybkoscY;
    else return - mSzybkoscY;
   
}
Plik do kompilacji:
mario
P-6301
DejaVu
» 2009-05-02 11:54:46
Nie używaj funkcji clock() w swoim programie.
P-6306
steckel
Temat założony przez niniejszego użytkownika
» 2009-05-02 12:02:56
Ale dlaczego? Jest ona za wolna? Niedokładna?
P-6309
DejaVu
» 2009-05-02 12:06:57
Jest przede wszystkim niedokładna :) Poczytaj kurs allegro - w nim znajdziesz mechanizmy, które się stosuje do pisania gier. Kurs jest krótki tak więc myślę, że szybko znajdziesz to co Ciebie interesuje. Generalnie chodzi o timer'y - w spisie treści znajdziesz to.

/edit:
http://kursy.ddt.pl/?TutorialId=7
P-6310
steckel
Temat założony przez niniejszego użytkownika
» 2009-05-12 21:22:56
To chyba nie tylko problem funkcji clock(), gdyż po jej skomentowaniu postac zachowuje się tak samo.
P-6776
DejaVu
» 2009-05-12 21:41:39
Ja ten Twój cały kod wziąłem i skompilowałem. Jak wywalisz wszystkie wystąpienia wspomnianej funkcji to kod działa szybko. Poczytaj o timerach.
P-6778
« 1 »
  Strona 1 z 1