• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

[SFML] Silnik animowania postaci (Ocena / Testy)

VPS Starter Arubacloud
0 głosów
366 wizyt
pytanie zadane 3 stycznia 2016 w C i C++ przez arek01996 Stary wyjadacz (12,100 p.)

Witam,

Stworzyłem parę klas odpowiadających za to że parę elementów np ręka czy noga złączyć ze sobą i dzięki temu uzyskiwać animację.

wygląda to w ten sposób:
 https://www.dropbox.com/s/r24oxfpgkx08kt6/AnimacjaDemo.rar?dl=0

Jak widać mając parę obrazków udało mi się stworzyć postać która emituje ruch.

W każdym razie użyłem rozwiązać z nowego Cpp 11 i boję się że mogą być niefunkcjonalne niewydajne etc.

 

System działa na prostej zasadzie. Tworzę obiekt dodaje do niego obrazki i piszę wyrażenie lambda uruchamiane w funkcji update. Te wyrażenia odpowiadają w jaki sposób ma być animowana postać. Tutaj dorzucam main takiej animacji prezentujący działanie: (Zamiast w main lepiej zrobić to w jakiejś klasie np Player, bo wiadomo są różne animacje idzWLewo, w prawo, walcz, etc).

System ma jeszcze wiele braków ale nie chce tego rozwijać jeśli ma się okazać że rozwiązanie nie jest zbyt optymalne etc... Poczekam na wasze opinie.

Tutaj main jak to wygląda:

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <iostream>
#include <functional>

#include "Animation.h"

using namespace std;
using namespace std::placeholders;

float number = 10;
int ch = 1;
int * chW = &ch;
float * testHere = &number; // Just for test

// Function given to the Animation Object responsible for animation
void walk( Animation * object, float dT, float angel )
{
    auto obj = bind(&Animation::getElement, object, _1);

    obj("OUT_ARM")->setRotateCenter(14, 15);
    obj("IN_ARM")->setRotateCenter(14, 15);

    obj("IN_ARM")->setRotation(angel);
    obj("OUT_ARM")->setRotation(-angel);

    obj("OUT_LEG")->setRotateCenter(14, 0);
    obj("IN_LEG")->setRotateCenter(14, 0);

    obj("IN_LEG")->setRotation(angel*0.4);
    obj("OUT_LEG")->setRotation(-angel*0.4);

    obj("HEAD")->setRotateCenter(32,64);
    obj("HEAD")->setRotation(angel*0.1);

}

// Function given to the Animation Object responsible for animation
void claun( Animation * object, float dT, float angel )
{
    auto obj = bind(&Animation::getElement, object, _1);

    *testHere = *testHere + 190*dT * *chW;

    if(*testHere > 50 || *testHere < -50)
        *chW=*chW*(-1);

    obj("OUT_ARM")->setRotateCenter(14, 15);
    obj("IN_ARM")->setRotateCenter(14, 15);
    obj("OUT_LEG")->setRotateCenter(14, 0);
    obj("IN_LEG")->setRotateCenter(14, 0);

    obj("IN_ARM")->setRotation(270-*testHere);
    obj("OUT_ARM")->setRotation(270+*testHere);
    obj("IN_LEG")->setRotation(330-*testHere);
    obj("OUT_LEG")->setRotation(330+*testHere);

    obj("IN_ARM")->move(*testHere*0.2*dT, 0);
    obj("OUT_ARM")->move(*testHere*0.2*dT, 0);


}

int main()
{
    sf::ContextSettings s;

    s.antialiasingLevel = 32;
    s.depthBits = 24;

    // Creating window
    sf::RenderWindow WindowApp(sf::VideoMode(1024, 600), "jump", sf::Style::Default ,s);
    //WindowApp.setVerticalSyncEnabled(true);
    
    //Create new animation Object
    Animation a(100, 200);
    
    // Add elements to animate object (Position is relative to mother)
    a.createElement("head.png", "HEAD", 82, 0);
    a.createElement("arm.png", "OUT_ARM", 100, 54 );
    a.createElement("leg.png", "OUT_LEG", 100, 115);
    a.createElement("body.png", "BODY", 92, 64);
    a.createElement("leg.png", "IN_LEG", 100, 115);
    a.createElement("arm.png", "IN_ARM", 100, 54 );

    //Create new animation object
    Animation b(100, 200);

    //Add elements to animate object (Position is relative to mother)
    b.createElement("head.png", "HEAD", 82, 0);
    b.createElement("arm.png", "OUT_ARM", 100, 54 );
    b.createElement("leg.png", "OUT_LEG", 100, 115);
    b.createElement("body.png", "BODY", 92, 64);
    b.createElement("leg.png", "IN_LEG", 100, 115);
    b.createElement("arm.png", "IN_ARM", 100, 54 );

    // This line is responsible to scale object head (now he will look in other direction) 
    b.getElement("HEAD") -> getDraw() -> setScale( sf::Vector2f( - 1, 1 ) );

    //Create new animation object
    Animation c(100, 200);

    //Add elements to animate object (Position is relative to mother)
    c.createElement("head.png", "HEAD", 82, 0);
    c.createElement("arm.png", "OUT_ARM", 100, 54 );
    c.createElement("leg.png", "OUT_LEG", 100, 115);
    c.createElement("body.png", "BODY", 92, 64);
    c.createElement("leg.png", "IN_LEG", 100, 115);
    c.createElement("arm.png", "IN_ARM", 100, 54 );

    //Setting position of object
    a.setPosition(300,100);
    b.setPosition(500, 100);
    c.setPosition(700, 100);

    //Adding function created in top to the Object
    a.createFunction(walk, "WALK" );
    b.createFunction(walk, "WALK" );
    c.createFunction(walk, "WALK" );

    //Began to animate function called WALK if you use function ( create ) without string all created functions will run animate
    a.startAnimation("WALK");
    b.startAnimation("WALK");
    c.startAnimation();

    //Just delta time
    sf::Clock dT;

    while (WindowApp.isOpen())
    {
        sf::Event event;

        while (WindowApp.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                WindowApp.close();

            if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::D)
                c.stopAnimation();

            if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::S){
                //Deleting function from object
                b.deleteFunction("WALK");
                // Adding a new function to object
                b.createFunction(claun, "Claun");
                // Begin animate this function
                b.startAnimation();
            }

        }
        float delta = dT.restart().asSeconds();
        //Just update state
        a.Update(delta);
        b.Update(delta);
        c.Update(delta);

        WindowApp.clear();
        //Just draw state
        WindowApp.draw(a);
        WindowApp.draw(b);
        WindowApp.draw(c);
        WindowApp.display();
    }

    return EXIT_SUCCESS;
}

Tutaj pliki cpp i headers: trzeba mieć zlinkowaną bibliotekę SFML

https://www.dropbox.com/s/nsg8isaj9ghmjrr/Animacja.rar?dl=0

Wypali to dodam na githuba :3

Pozdrawiam i dziękuje z góry za testy.

1 odpowiedź

+1 głos
odpowiedź 3 stycznia 2016 przez niezalogowany
Wolałbym jakiś film niż aplikację którą muszę pobrać, ale dobra.

W sumie silnik to na ten moment za dużo powiedziane. Efekt wygląda imponująco (nazewnictwo trochę kuleje), ale w sumie jest ok.
komentarz 3 stycznia 2016 przez arek01996 Stary wyjadacz (12,100 p.)
Dziękuje za odpowiedź. Czyli przekazywanie funkcji do vektora na rzecz ich wykonania w obiekcie jest dopuszczalna ? O to się martwię najbardziej. I te funkcje przekazane muszą działać na wskaźnikach jeśli mają mieć zapisaną jakąś wartość z poza obiektu, jedyny minus ale to co najważniejsze jest dT i jakaś zmienna co odpowiada za rotacje.

 

Nazewnictwo w pliku main.cpp rzeczywiście kuleje ale to tylko poglądowo zostało wykonane. Myśle że w pliku ParticleAnimation.h oraz cpp jest troszeczkę lepiej :)
komentarz 3 stycznia 2016 przez arek01996 Stary wyjadacz (12,100 p.)
Początkowo chciałem aby funkcja wirtualna update była przyjmowała argument klasy Animation i użytkownik za pomocą this mógłby edytować funkcję wedle życzenia ale nie chciałem obiektu ograniczać do jednej metody bo byłoby to dość niewydajne. Ruch w drugą stronę albo jakieś pochylenie = nowy obiekt..

Podobne pytania

+4 głosów
1 odpowiedź 1,975 wizyt
pytanie zadane 21 kwietnia 2015 w C i C++ przez Ehlert Ekspert (214,100 p.)
0 głosów
1 odpowiedź 366 wizyt
pytanie zadane 22 czerwca 2021 w C i C++ przez burn3ov Nowicjusz (120 p.)
0 głosów
2 odpowiedzi 632 wizyt
pytanie zadane 29 stycznia 2017 w C i C++ przez Pajdas Mądrala (5,930 p.)

93,012 zapytań

141,977 odpowiedzi

321,266 komentarzy

62,354 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...