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

Obracające się obiekty w klasie sf::Vertex

Ostatnio zmodyfikowano 2020-07-11 17:50
Autor Wiadomość
BraveRat
Temat założony przez niniejszego użytkownika
Obracające się obiekty w klasie sf::Vertex
» 2020-07-08 22:08:32
To znowu ja. W moim ostatnim temacie pisałem, że mam na scenie wiele drzew z dwóch grafik i dążę do zminimalizowania uczucia monotonii. Uznałem, że dobrym pomysłem będzie jak pnie drzew będą rysowane osobno od gałęzi a jeszcze lepszym jak te gałęzie będą się kołysać na wietrze. Rozpisałem więc taką klasę:
Plik h:
C/C++
class Branch
    : public sf::Drawable
     , public sf::Transformable
{
public:
    bool load( const std::string & name, sf::Vector2u size, sf::Vector2f position1, sf::Vector2f position2, sf::Vector2f position3, sf::Vector2f position4, sf::Vector2f position5, unsigned int count, short side1, short side2, short side3, short side4, short side5 );
    void rotate( double frame, int actualframe );
private:
   
    virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const
    {
        states.transform *= getTransform();
       
        states.texture = & m_tileset;
       
        target.draw( m_vertices, states );
    }
   
    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
    sf::Clock animationclock;
};
I plik cpp:
C/C++
bool Branch::load( const std::string & name, sf::Vector2u size, sf::Vector2f position1, sf::Vector2f position2, sf::Vector2f position3, sf::Vector2f position4, sf::Vector2f position5, unsigned int count, short side1, short side2, short side3, short side4, short side5 ) //zmienne side określają który z kolei ma być lustrzanym odbiciem oryginału (w razie gdyby były np. po drugiej stronie pnia)
{
    if( !m_tileset.loadFromFile( name ) )
         return false;
   
    if( count >= 6 ) //Rysuję max 5 bo widok wszystkich gałęzi kołyszących się synchronicznie kuł by w oczy
         return false;
   
    m_vertices.setPrimitiveType( sf::Quads );
    m_vertices.resize( count * 4 );
   
    short currentSide;
    sf::Vector2f currentPosition;
    for( unsigned int i = 0; i < count; ++i )
    {
        switch( i )
        {
        case 0:
            currentSide = side1;
            currentPosition = position1;
            break;
        case 1:
            currentSide = side2;
            currentPosition = position2;
            break;
        case 2:
            currentSide = side3;
            currentPosition = position3;
            break;
        case 3:
            currentSide = side4;
            currentPosition = position4;
            break;
        case 4:
            currentSide = side5;
            currentPosition = position5;
            break;
        }
        sf::Vertex * quad = & m_vertices[ i * count * 4 ];
       
        switch( currentSide )
        {
        case 0:
            quad[ 0 ].position = sf::Vector2f( currentPosition.x, currentPosition.y );
            quad[ 1 ].position = sf::Vector2f(( size.x + currentPosition.x ), currentPosition.y );
            quad[ 2 ].position = sf::Vector2f(( size.x + currentPosition.x ),( size.y + currentPosition.y ) );
            quad[ 3 ].position = sf::Vector2f( currentPosition.x,( size.y + currentPosition.y ) );
            break;
        case 1:
            quad[ 1 ].position = sf::Vector2f( currentPosition.x, currentPosition.y );
            quad[ 0 ].position = sf::Vector2f(( size.x + currentPosition.x ), currentPosition.y );
            quad[ 3 ].position = sf::Vector2f(( size.x + currentPosition.x ),( size.y + currentPosition.y ) );
            quad[ 2 ].position = sf::Vector2f( currentPosition.x,( size.y + currentPosition.y ) );
            break;
        }
       
    }
   
    return true;
}
void Branch::rotate( double frame, int actualframe )
{
    if( animationclock.getElapsedTime().asSeconds() >= frame )
    {
        animationclock.restart();
        //kod na obracanie
        actualframe =( actualframe + 1 ) % 4;
    }
}
I teraz nie wiem jaki zrobić kod na obracanie tych vertexów z osobna bo gdybym zrobił rotate to obróciły by się wszystkie. Z kolei rysowanie 20 sprite'ów byłoby chyba mało praktyczne. A do tego mam dodatkowy problem jeśli w próbuję stworzyć jej obiekt:
C/C++
Branch branches1;
if( !branches1.load( "branch.png", sf::Vector2u( 97, 98 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), 1, 0, 0, 0, 0, 0 ) );

return - 1;
To okno zaraz po otworzeniu się zamyka a nazwa i rozmiar pliku na 100% są poprawne. Z góry dziękuję za pomoc.
P-177358
BraveRat
Temat założony przez niniejszego użytkownika
» 2020-07-09 11:07:21
Dobra z tym drugim już sobie poradziłem po prostu po if  był ;
P-177361
BraveRat
Temat założony przez niniejszego użytkownika
» 2020-07-09 11:36:43
W nagłym przypływie weny zmodyfikowałem tą klasę do:
Plik h:
C/C++
class Branch
    : public sf::Drawable
     , public sf::Transformable
{
public:
    Branch( int a, sf::Vector2u s, sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4, sf::Vector2f p5, unsigned int c, unsigned int h );
    bool load( const std::string & name, short side1, short side2, short side3, short side4, short side5 );
    void rotate( double frame, int angle );
private:
   
    virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const
    {
        states.transform *= getTransform();
       
        states.texture = & m_tileset;
       
        target.draw( m_vertices, states );
    }
    sf::Vector2u size;
    sf::Vector2f position1;
    sf::Vector2f position2;
    sf::Vector2f position3;
    sf::Vector2f position4;
    sf::Vector2f position5;
    int actualframe;
    unsigned int count;
    unsigned int height;
    sf::VertexArray m_vertices;
    sf::Texture m_tileset;
    sf::Clock animationclock;
};
plik cpp:
C/C++
Branch::Branch( int a, sf::Vector2u s, sf::Vector2f p1, sf::Vector2f p2, sf::Vector2f p3, sf::Vector2f p4, sf::Vector2f p5, unsigned int c, unsigned int h )
{
    a = actualframe;
    s = size;
    p1 = position1;
    p2 = position2;
    p3 = position3;
    p4 = position4;
    p5 = position5;
    c = count;
    h = height;
   
}
bool Branch::load( const std::string & name, short side1, short side2, short side3, short side4, short side5 )
{
    if( !m_tileset.loadFromFile( name ) )
         return false;
   
    if( count >= 6 )
         return false;
   
    m_vertices.setPrimitiveType( sf::Quads );
    m_vertices.resize( count * height * 4 );
   
    short currentSide;
    sf::Vector2f currentPosition;
    for( unsigned int i = 0; i < count; ++i )
    {
        for( unsigned int j = 0; j < height; ++j )
        {
           
            switch( i )
            {
            case 0:
                currentSide = side1;
                currentPosition = position1;
                break;
            case 1:
                currentSide = side2;
                currentPosition = position2;
                break;
            case 2:
                currentSide = side3;
                currentPosition = position3;
                break;
            case 3:
                currentSide = side4;
                currentPosition = position4;
                break;
            case 4:
                currentSide = side5;
                currentPosition = position5;
                break;
            }
            sf::Vertex * quad = & m_vertices[( i + j * count ) * 4 ];
           
            switch( currentSide )
            {
            case 0:
                quad[ 0 ].position = sf::Vector2f( currentPosition.x, currentPosition.y );
                quad[ 1 ].position = sf::Vector2f(( size.x + currentPosition.x ), currentPosition.y );
                quad[ 2 ].position = sf::Vector2f(( size.x + currentPosition.x ),( size.y + currentPosition.y ) );
                quad[ 3 ].position = sf::Vector2f( currentPosition.x,( size.y + currentPosition.y ) );
                break;
            case 1:
                quad[ 1 ].position = sf::Vector2f( currentPosition.x, currentPosition.y );
                quad[ 0 ].position = sf::Vector2f(( size.x + currentPosition.x ), currentPosition.y );
                quad[ 3 ].position = sf::Vector2f(( size.x + currentPosition.x ),( size.y + currentPosition.y ) );
                quad[ 2 ].position = sf::Vector2f( currentPosition.x,( size.y + currentPosition.y ) );
                break;
            }
            quad[ 0 ].texCoords = sf::Vector2f( 0, 0 );
            quad[ 1 ].texCoords = sf::Vector2f( size.x, 0 );
            quad[ 2 ].texCoords = sf::Vector2f( size.x, size.y );
            quad[ 3 ].texCoords = sf::Vector2f( 0, size.y );
        }
    }
   
    return true;
}
void Branch::rotate( double frame, int angle )
{
    sf::Vector2f currentPosition;
    for( unsigned int i = 0; i < count; ++i )
    {
        for( unsigned int j = 0; j < height; ++j )
        {
           
            switch( i )
            {
            case 0:
                currentPosition = position1;
                break;
            case 1:
                currentPosition = position2;
                break;
            case 2:
                currentPosition = position3;
                break;
            case 3:
                currentPosition = position4;
                break;
            case 4:
                currentPosition = position5;
                break;
            }
           
            if( animationclock.getElapsedTime().asSeconds() >= frame )
            {
                animationclock.restart();
                //quad[0].position = sf::Vector2f(currentPosition.x + angle, currentPosition.y + angle);
                //quad[1].position = sf::Vector2f((size.x + currentPosition.x - angle), currentPosition.y - angle);
                //quad[2].position = sf::Vector2f((size.x + currentPosition.x + angle), (size.y + currentPosition.y + angle));
                //quad[3].position = sf::Vector2f(currentPosition.x - angle, (size.y + currentPosition.y - angle));
               
                actualframe =( actualframe + 1 ) % 4;
            }
        }
    }
}
Main:
C/C++
Branch branches1( 0, sf::Vector2u( 97, 98 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), sf::Vector2f( 0, 0 ), 1, 1 );
if( !branches1.load( "branch.png", 0, 0, 0, 0, 0 ) )
     return - 1;

Tylko teraz nie weim jak te quady które zamieniłem w komentarz ogarnąć.
P-177362
pekfos
» 2020-07-11 12:42:18
Co dokładnie chcesz osiągnąć? Może zobacz jak wygląda macierz obrotu w 2D i zastosuj analogiczne obliczenia dla wybranych wierzchołków. Albo użyj sf::Transform, które już to implementuje.
P-177364
BraveRat
Temat założony przez niniejszego użytkownika
» 2020-07-11 17:36:03
Może nie wyraziłem się jasno ale chodzi mi o to by każdy vertex obracał się osobno i żeby mu było można przypisać coś w rodzaju środka bo jakbym użył rotate() to obróci się cały obiekt.
P-177365
pekfos
» 2020-07-11 17:46:04
Może zobacz jak wygląda macierz obrotu w 2D i zastosuj analogiczne obliczenia dla wybranych wierzchołków. Albo użyj sf::Transform, które już to implementuje.
https://www.sfml-dev.org​/documentation/2.5.1​/classsf_1_1Transform.php#ab42a0bb7a252c6d221004f6372ce5fdc
P-177366
BraveRat
Temat założony przez niniejszego użytkownika
» 2020-07-11 17:50:09
Dzięki
P-177367
« 1 »
  Strona 1 z 1