Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - snz

Pages: [1]
1
General / Strange animation behaviour
« on: October 17, 2018, 02:42:02 pm »
Im writing MK clone.
I wrote Animation class:

#ifndef ANIMATOR_H
#define ANIMATOR_H

#include <vector>

#include "SFML\Graphics.hpp"

class Animator {
public:
        Animator();
        ~Animator();

        void addFrame(sf::IntRect frame);
        void play(sf::Time duration, bool loop);
        bool isPlaying() const;

        void update(sf::Time delta);

        // Sprite contains current frame
        void switchFrame(sf::Sprite& sprite);

private:
        std::vector<sf::IntRect> _frames;
        unsigned _currentFrame;
        bool _loop;
        bool _isPlaying;
        sf::Time _duration;
};
 

#include "Animator.h"

Animator::Animator() : _currentFrame(0), _isPlaying(false), _duration(sf::Time::Zero), _loop(false) {}


Animator::~Animator() {
}

void Animator::addFrame(sf::IntRect frame) {
        _frames.push_back(frame);
}

void Animator::play(sf::Time duration, bool loop) {
        _isPlaying = true;
        _duration = duration;
        _loop = loop;
}

bool Animator::isPlaying() const {
        return _isPlaying;
}

void Animator::update(sf::Time delta) {
        if (!isPlaying())
                return;
       

        // Local time buffer
        static sf::Time buffer = sf::Time::Zero;

        // Update with an elapsed time
        buffer += delta;

        // Compute single frame duration
        sf::Time frameDuration = _duration / static_cast<float>(_frames.size());

        // Time to switch frame
        if (buffer >= frameDuration) {
                _currentFrame++;
               
                // If looping animation is not allowed
                if (_currentFrame >= _frames.size()) {
                        if (!_loop)
                                _isPlaying = false;

                        _currentFrame = 0;
                }

                buffer -= frameDuration;
        }
        printf("%d\n", _currentFrame);
}

void Animator::switchFrame(sf::Sprite& sprite) {
        sprite.setTextureRect(_frames[_currentFrame]);
}
#endif // ANIMATOR_H
 

And in raiden's class derived from Character class, with is derived from Transformable and Drawable, created 2 animators: idle and idle_electricity.
I wanted them to play simultaneously..

#ifndef RAIDEN_H
#define RAIDEN_H

#include "Character.h"
#include "Animator.h"

class Raiden : public Character {
public:
        Raiden();
        ~Raiden();

        virtual void update(sf::Time delta);

private:
        void draw(sf::RenderTarget& target, sf::RenderStates states) const;

private:
        sf::Texture _spritesheet;

        sf::Sprite _visual;
        sf::Sprite _visualElectro;

        Animator _idle;
        Animator _idleElectro;
};

#endif // RAIDEN_H



Raiden::Raiden() {
        if (!_spritesheet.loadFromFile("Assets/raiden-s.png"))
                throw std::runtime_error("Unable to load raiden's spritesheet");
        _visual.setTexture(_spritesheet);
        _visualElectro.setTexture(_spritesheet);

        setOrigin(27, 51);
        setPosition(300, 300);

        // Idle animation
        for (unsigned i = 1; i <= 271; i += 54)
                _idle.addFrame(sf::IntRect(i, 14, 54, 102));

        // Idle electricity animation
        for (unsigned i = 1; i <= 811; i += 54)
                _idleElectro.addFrame(sf::IntRect(i, 132, 54, 102));

       
        _idle.play(sf::seconds(1), true);
        _idleElectro.play(sf::seconds(2), true);
       
}


Raiden::~Raiden() {
}

void Raiden::update(sf::Time delta) {
        // Animation update
        _idle.update(delta);
        _idle.switchFrame(_visual);
       
        _idleElectro.update(delta);
        _idleElectro.switchFrame(_visualElectro);

        Character::update(delta);
}

void Raiden::draw(sf::RenderTarget& target, sf::RenderStates states) const {
        states.transform *= getTransform();
        target.draw(_visual, states);
        target.draw(_visualElectro, states);
}

What is strange? (Note printf("%d\n", _currentFrame); in animator update method )
While both of them are being played, only electicity's one animation is playing, but idle's one (raiden itself) stands still without changes.
For idle's one it prints 0 as currentFrame, for electricity's one - normally cycled
But, when electicity's one _loop is being set to false, it's stopped (which is ok), but idle's one starts cycling thru frames.. (animation is played) Why is that ?

+ dont know why, after resizing a window, currentFrame of idle's one changes (when both _loop are being set to true..) I mean, i feel like _idle_electricity's  animation depends on time, but _idle's one only to window resizing or window clicks..

Pages: [1]