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

[C++][SFML] Argumenty metody, a dziedziczenie z różnych klas nadrzędnych funkcji wirtualnych

Ostatnio zmodyfikowano 2015-11-20 21:46
Autor Wiadomość
arczi14
Temat założony przez niniejszego użytkownika
[C++][SFML] Argumenty metody, a dziedziczenie z różnych klas nadrzędnych funkcji wirtualnych
» 2015-11-20 16:12:01
Witam,

Mam problem z moim projektem. Piszę własny dość prosty silnik graficzy oparty na SFML, jakieś proste shadery z cząsteczkami, obsługa rozdzielczosci plików językowych ini itp. i Natknąłem się na poważny problem którego od miesiąca nie potrafię przeskoczyć.

Otóż zakładam że każdy może zrobić sobie klasę w oparciu o klasę nadrzedną Updateable, która umożliwia

dodanie jako agrumentu do klasy Engine własnej klasy dzięki czemu rozwiązałem problem aktualizacji stanu gry.

Wygląda to mniejwięcej tak (kod skróciłem dla przejrzystości ):

C/C++
// plik engine.cpp

void Engine::Update( float deltaInSeconds )
{
    for( auto It = allObjectsContainer.begin(); It != allObjectsContainer.end(); It++ )
    {
        ( * It )->Update( deltaInSeconds );
       
        if(( * It )->Destroy() ) {
            allObjectsContainer.erase( It );
            break;
        }
    }
}


// plik engine.h
class Engine
{
   
public:
   
    void Update( float );
    void addObject( Updateable & object );
   
private:
    vector < Updateable *> allObjectsContainer;
   
};
// Plik dowolnej własnej klasy .cpp

C/C++
SpriteEffect::SpriteEffect( string path,
sf::Vector2i _spriteSize,
sf::Vector2f _position,
int _FPS_limit,
int _status,
bool _autoDelete )
    : spriteSize( _spriteSize )
     , status( _status )
     , autoDelete( _autoDelete )
{
   
   
}


void SpriteEffect::Update( float dT )
{
    if( activity != Activity::Active )
         return void();
   
    time += sf::seconds( dT );
    int x, y;
   
    if( time.asSeconds() >= FPS_PER_SEC )
    {
        // Reset time
        time = sf::seconds( 0 );
       
        y = int( frame / lengthOfTexture.x );
        x = frame % int( lengthOfTexture.x );
        drawableSprite.setTextureRect( sf::IntRect( x * spriteSize.x, y * spriteSize.y,
        spriteSize.x, spriteSize.y ) );
       
        //What to do if texture get to the end
        if(( lengthOfTexture.y * lengthOfTexture.x ) - 1 <= frame )
        {
            switch( status )
            {
            case STATUS::Repeat:
                {
                    frame = 0;
                }
                break;
               
            case STATUS::Once:
                {
                   
                    activity = Activity::Disactive;
                    frame = 0;
                    time = sf::seconds( 0 );
                   
                    if( autoDelete )
                         destroyQueue = true;
                   
                }
                break;
               
            }
        }
       
        // After update increase frame
        frame++;
       
    }
}

void SpriteEffect::draw( sf::RenderTarget & target, sf::RenderStates states ) const
{
    if( activity == Activity::Active )
         target.draw( drawableSprite );
   
}
C/C++
// plik header wlasnej klasy

class SpriteEffect
    : public Updateable
     , public sf::Drawable
{
   
    enum STATUS
    {
        Once = 0x10A,
        Repeat = 0xA0A
    };
   
protected: // Protected functions
    virtual void Update( float );
   
private: // Private functions
    virtual bool Destroy() const; // Function charge of delete object from memory when bool in constructor is TRUE
    virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
   
   
private: // Private variable & class
   
   
};

I teraz zmagam się dla mnie z poważnym problemem a dla innych może to będzie błache.

Jak widać wlasna klasa w tym przypadku SpriteEffect ma funkcję wirtualną drawable dzięki której możemy rysować nasz dowolny obiekt przekazując nasz obiekt tak samo jak inne obiekty z SFML

czyli np

Window.draw(Moj Obiekt Ktory Dziedziczy Z sf::Drawable)

Tylko że to jest nie wygodne i aktualnie zmagam się z klasą która sama się z kontenera usuwa po jakims czasie, a musze ją jeszcze osobno rysować więc to dość uciążliwe bo jak się przestaje updatować to również niech przestanie być na ekranie.

Do engine ten obiekt przekazuje w funkcji void addObject ( Updateable &object);

który dodaje do kontenera i updatuje stan gry chciałbym żeby w tej samej pętli również rysował te obiekty. Jak zrobić żeby w tej funkcji przekazać również funkcję wirtualną która dziedziczy z innej klasy niż updatable ?

przykładowy main

SpriteEffect fly;

Engine engine(*WindowApp);
engine.addObject(fly); // Od teraz obiekt fly updatuej sie zgodnie z funkcja wirtualna zawarta w klasie,

niektóre obiekty trwają pare sekund i znikają a i tak musze je za każdym razem rysować co jest cholernie niewygodne

        WindowApp->draw(fly);

        WindowApp->display();

da się to jakoś rozwiązać ?

Pozdrawiam.
P-140443
Monika90
» 2015-11-20 17:09:48
Skoro obiekty typu Updatable mają być też typu sf::Drawable, to niech Updatable dziedziczy z sf::Drawable.

Pętla w funkcji Update nie wygląda na poprawną.
P-140449
arczi14
Temat założony przez niniejszego użytkownika
» 2015-11-20 18:12:59
Robiłem to w ten sposób i program dalej zachowywał się w ten sposób.
Nie mogłem użyć tej wirtualnej funkcji w pętli.
P-140452
Monika90
» 2015-11-20 20:46:58
Nie możesz wywołać sf::Drawable::draw() bo jest prywatna. Dziedziczenie po sf::Drawable nie jest po to żebyś mógł bezpośrednio wywoływać draw, ale po to żebyś mógł przekazać swój obiekt do funkcji sf::RenderTarget::draw(), sf::RenderWindow::draw() itp.
P-140460
arczi14
Temat założony przez niniejszego użytkownika
» 2015-11-20 20:56:52
C/C++
for( auto It = allObjectsContainer.begin(); It != allObjectsContainer.end(); It++ )
{
    ( * It )->Update( deltaInSeconds );
   
    if(( * It )->Destroy() ) {
        allObjectsContainer.erase( It );
        break;
    }
   
    WindowApp->draw( * It );
}

Window app to obiekt sf::RenderWindow.
I wywala błąd mimo tego że Updatable dziedziczy teraz z sf::Drawable
P-140461
Monika90
» 2015-11-20 21:12:31
C/C++
WindowApp->draw( ** It );
Dwie gwiazdki tam powinny być.
P-140463
arczi14
Temat założony przez niniejszego użytkownika
» 2015-11-20 21:46:11
Ooo działa, ale program wykonuje wtedy funkcję z klasy Updatable a nie Tej własnej która z Updateable dziedziczy ?
ps. Dzięki za dotychczasową pomoc.
P-140469
« 1 »
  Strona 1 z 1