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

Poprawa kodu /sfml/ /animacja/

VPS Starter Arubacloud
0 głosów
643 wizyt
pytanie zadane 29 stycznia 2017 w C i C++ przez Pajdas Mądrala (5,930 p.)
Witam, napisałem proste sterowanie animacjami do gry i chce poświęcić jeden dzień na dopracowanie kodu, aby był wydajny, wygodny i przejrzysty.

Kod ma być użyty w planowanej klasie ruch, która będzie obsługiwana przez klasę sterowanie,
klasa animacja i ruch ma być "silnikiem" (kodem uniwersalnym) a klasa sterowanie ma być rzeczywistym kodem gry który korzysta z "silnika". Aby animacja nie była szarpana przewiduję odgrywanie animacji i nieprzerwanie ruchu, dopóki nie skończy się odgrywać.

Wklajem kod na wklejce aby nie zaśmiecać posta i proszę o komentarz i porady pamiętając o przewidywanym celu tego kodu :)

Animacja.h
http://www.wklej.org/id/3030512/

Animacja.cpp
http://www.wklej.org/id/3030514/

Gracz.h
http://www.wklej.org/id/3030516/

Gracz.cpp
http://www.wklej.org/id/3030518/

2 odpowiedzi

+3 głosów
odpowiedź 30 stycznia 2017 przez Ehlert Ekspert (214,220 p.)
wybrane 30 stycznia 2017 przez Pajdas
 
Najlepsza

Witaj,

Przygotuj się na dużą dawkę konstruktywnej krytyki laugh

Kod:

  • Mieszasz polski z angielskim. Niedobrze.
  • Jak na kod, który ma być wielokrotnie wykorzystywany nie napisałeś dokumentacji a nazewnictwo nie pomaga
  • Gracz::configureWindow wcale nie konfiguruje okna.

Teraz logika.

  • Zacznijmy od założeń. proste sterowanie animacjami do gry Ok! Kod ma być użyty w planowanej klasie ruch i tu jest błąd projektowy. Dlaczego animacja ma być w klasie ruchu? Animacja będąca elementem efektów graficznych ma być elementem klasy związanej z fizyką? Klasa musi spełniać jedno zadanie i mieć jedną odpowiedzialność.
  • Taka kalkulacja na szybko. sizeof sf::Texture to 40 bajtów. Każda animacja zawiera teksturę. Każdy gracz dajmy na to 4 animacje. Piszemy skromny system cząsteczkowy na 1000 obiektów. 4*1000*rozmiar_obrazka. Wydajność LEŻY.
  • Pomysł polegający na tym, że każda jednostka będzie mieć własny zegar jest co najmniej dziwny. Nie mówiąc o tablicy zegarów. W Supreme Commander było nawet ponad tysiąc jednostek na mapę. Dajmy każdej 2 zegary. 
    Tak wygląda najlepsze założenie:
    void Unit::update(const sf::Time _dt)
    {
    reloadGunAccumulator += _dt;
    animationAccumulator += _dt;
    useBazookaAccumulator += _dt;
    if (reloadGunAccumulator.asSeconds() > 2) {
       this->gun->reload();
       reloadGunAccumulator = sf::Time::Zero;
    }
    if (animationAccumulator >= 0.1) {
       this->updateFrame();
       animationAccumulator = sf::Time::Zero;
    }
    if (useBazookaAccumulator >= 10) {
       this->bazooka->shoot();
       useBazookaAccumulator = sf::Time::Zero;
    }
    }

    Takie zastosowanie pozwala na użycie jednego zegara w całej grze.

  • Jedyna produkcja w której postać miała pojęcie o istnieniu okna to Animation vs Animator. Używaj dziedziczenia z sf::Drawable

komentarz 30 stycznia 2017 przez adrian17 Ekspert (349,960 p.)

const sf::Time& _dt

(to ma tylko lekko kopiowalny long long int, prościej kopiować; jak poprawisz to schowam)

komentarz 30 stycznia 2017 przez Pajdas Mądrala (5,930 p.)
edycja 30 stycznia 2017 przez Pajdas
To, że każda animacja ma oddzielny czas to efekt tego, że chce aby można było odgrywać animację z różną szybkością

Sizeof sf::Czas = 8, a co do ilości tekstur poprawiłem to trochę, jeszcze nad tym pracuje.
Dziękuję za odpowiedz, za niedługo podeślę wam poprawiony kod do oceny.

Usunąłem klasę gracz i dodałem kilka funkcji do Animacja.
Klasa animacja ma docelowo oddawać odpowiedni sf::Sprite i ma być niezależna od jakiejkolwiek klasy.

Klasa Ruch będzie przyjmować sf::Sprite od klasy animacja i przemieszczać obraz z odpowiednią szybkością na klatkę (tak aby np. noga która odpycha ciało stała w miejscu a nie "ślizgała" się)

Proszę jeszcze o komentarz do tej wypowiedzi

Lekko zmodyfikowany kod:
https://github.com/pajdas/Sfml-project
komentarz 30 stycznia 2017 przez Ehlert Ekspert (214,220 p.)

Poczytaj czym jest SOLID bo wszystko co planujesz nie jest z nim zgodne. Klasa move nie powinna mieć nic wspólnego ze spritem. Co najwyżej może mieć metodę wirtualną do przeciążenia w której będziesz przypisywać position do spritea z klasy move.

Masz wybór. Albo mnie się posłuchać i ogarnąć jak to powinno wyglądać, albo zrobić po swojemu i zakopać się w tym projekcie. Kod na pewno nie będzie uniwersalny, a zegar w klasie gracz przy którym się upierasz to implementacyjny absurd.

komentarz 30 stycznia 2017 przez Pajdas Mądrala (5,930 p.)

Nie do końca rozumiem, jeżeli

Klasa move nie powinna mieć nic wspólnego ze spritem

To czym ma ta klasa move ruszać, jak nie sprajtem

Albo mnie się posłuchać i ogarnąć jak to powinno wyglądać, albo zrobić po swojemu i zakopać się w tym projekcie

Trochę groźnie to zabrzmiało :) nie planuję Ciebie "niesłuchać" a ten ostatni kod jaki przesłałem to nie wszystko co zamierzam poprawić. Na razie rozwiązuje problem związany z czasem i nie zrobię wszystkiego na raz

komentarz 30 stycznia 2017 przez Ehlert Ekspert (214,220 p.)
class Move{
private:

float x,y;

protected:
virtual void assignPosition() = 0;
//...
public:
void updateMove(const sf::Time _dt) {
//...poruszamy
assignPosition();
}
sf::Vector2f getPosition() { return sf::Vector2f(x,y); }
}

Hero : public Move{
private:
sf::Sprite cos;
protected:
virtual void assignPosition() {
cos.setPosition(getPosition());
}
}

Można, Klasa move nic nie wie o istnieniu spirte'a.

komentarz 30 stycznia 2017 przez Pajdas Mądrala (5,930 p.)
Ok, dziękuję bardzo, przemyślę jeszcze wszystko
komentarz 30 stycznia 2017 przez Ehlert Ekspert (214,220 p.)

Zanim coś, to rzuć okiem na mój projekt wink

komentarz 30 stycznia 2017 przez Pajdas Mądrala (5,930 p.)
spoko, ja pierwotnie chciałem osiągnąć coś takiego
https://github.com/SFML/SFML/wiki/Source:-AnimatedSprite
ale jak pobrałem sobie to to szybko zauważyłem, że jak naciskam klawisz z dużą częstotliwością, to wygląda to jakby obiekt się ślizgał i dlatego chce zastosować w moim projekcie podział mapy na kafelkowy i odgrywanie animacji do końca, czyli jak zacząłeś to albo się skończy albo zawrócisz :)
komentarz 30 stycznia 2017 przez Ehlert Ekspert (214,220 p.)
To zależy od tego czy chcesz animację dziedziczyć czy zawierać.
0 głosów
odpowiedź 30 stycznia 2017 przez sofnir Gaduła (4,690 p.)
Hej, w sieci jest sporo przykładów:

https://www.youtube.com/watch?v=Aa8bXSq5LDE

https://www.binpress.com/tutorial/creating-a-city-building-game-with-sfml-part-3-textures-and-animations/125

Dlaczego klasa Gracz zawiera czas i okno? Tym powinna zajmować się pętla główna, a gracz jest osobnym bytem. Ja bym zrobił tak, że Gracz zawiera sprajta, któremu została ustawiona tekstura. Osobna klasa Animacja zawiera zmienna IntRect, który zawiera informację o tym, który fragment sprajta ma być wyświetlany i w pętli głównej gry robię update wszystkiego. Obiekt animacjaGracza dostaje czas z pętli głównej programu, sprawdza czy ma przeskoczyć na kolejną klatkę, a następnie dla obiektu gracz jest ustawiany IntRect (nowy lub stary, zależy czy minął pewien czas). W tym filmiku na yt gościu coś takiego robi, ale on zmienną IntRect traktuje jako publiczną - tak nie rób, stwórz sobie gettera :)

Podobne pytania

0 głosów
1 odpowiedź 367 wizyt
pytanie zadane 22 czerwca 2021 w C i C++ przez burn3ov Nowicjusz (120 p.)
+4 głosów
1 odpowiedź 1,987 wizyt
pytanie zadane 21 kwietnia 2015 w C i C++ przez Ehlert Ekspert (214,220 p.)
0 głosów
1 odpowiedź 366 wizyt
pytanie zadane 3 stycznia 2016 w C i C++ przez arek01996 Stary wyjadacz (12,100 p.)

93,032 zapytań

141,996 odpowiedzi

321,300 komentarzy

62,379 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!

...