user768417
user768417

Reputation:

Sprite not animating

I wrote two classes; Animation, and Actor. For some reason, the sprite image doesn't change. It stays the first frame the entire time. The code is fine I have no issues compiling, my logic is just wrong somewhere and it isn't acting how I expected it to.

Animation class declaration:

class Animation
{
public:
        Animation(std::string path, int frames);
        ~Animation();
        void nextFrame();
        void gotoStart();
        bool loadFrames();
        sf::Texture& getActiveFrame();

private:
        int frameCount;
        std::string pathToAnimation;
        int currentFrame;
        sf::Texture frame[];
};

Animation class implementation:

Animation::Animation(std::string path, int frames)
{
        pathToAnimation = path;
        frameCount = frames;
}

Animation::~Animation()
{
        // destructor
}

void Animation::nextFrame()
{
        if(currentFrame < frameCount)
        {
            currentFrame = 1;
        }
        else
            currentFrame += 1;
}

void Animation::gotoStart()
{
        currentFrame = 1;
}

bool Animation::loadFrames()
{
        for(int i = 01; i < frameCount; i++)
        {
            if(!frame[i].loadFromFile(pathToAnimation + std::to_string(i) + ".jpg")) return false;
        }
        return true;
}

sf::Texture& Animation::getActiveFrame()
{
    return frame[currentFrame];
}

Actor class declaration:

class Actor
{
public:
        Actor();
        ~Actor();
        void setActiveAnimation(std::shared_ptr<MaJR::Animation> anim);
        void draw(sf::RenderWindow& win);

private:
        sf::Sprite sprite;
        std::shared_ptr<MaJR::Animation> activeAnimation;
};

Actor class implementation:

Actor::Actor()
{
    // constructor
}

Actor::~Actor()
{
    // destructor
}

void Actor::setActiveAnimation(std::shared_ptr<MaJR::Animation> anim)
{
    activeAnimation = anim;
    activeAnimation->gotoStart();
}

void Actor::draw(sf::RenderWindow& win)
{
    sprite.setTexture(activeAnimation->getActiveFrame());
    win.draw(sprite);
    activeAnimation->nextFrame();
}

Here's the code to test it:

int main()
{
    sf::RenderWindow Window(sf::VideoMode(800, 600), "MaJR Game Engine Sandbox");

    std::shared_ptr<MaJR::Animation> DroneStandNorth = std::make_shared<MaJR::Animation>("./Assets/Sprites/Zerg/Units/Drone/Stand/North/", 61);
    if(!DroneStandNorth->loadFrames()) return EXIT_FAILURE;
    MaJR::Actor Drone;
    Drone.setActiveAnimation(DroneStandNorth);

    while(Window.isOpen())
    {
        sf::Event Event;
        while(Window.pollEvent(Event))
        {
            if(Event.type == sf::Event::Closed)
                Window.close();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
            Window.close();

        Window.clear();
        Drone.draw(Window);
        Window.display();
    }

    return 0;
}

I'm at a complete loss as to what's wrong here. If you want to compile everything yourself, here's the original files: http://www.filedropper.com/animationtesttar be sure to use -std=c++0x or whatever you have to do to use C++11 with your compiler.

Upvotes: 0

Views: 259

Answers (1)

Daniel Bickler
Daniel Bickler

Reputation: 1140

In your animation implementation, you have:

void Animation::nextFrame()
{
    if(currentFrame < frameCount)
    {
        currentFrame = 1;
    }
    else
        currentFrame += 1;
}

Since the currentFrame starts at 1, it will always be less than frameCount, so it will always be set to 1. Change to:

void Animation::nextFrame()
{
    if(currentFrame >= frameCount)
    {
        currentFrame = 1;
    }
    else
        currentFrame += 1;
}

This way, when the currentFrame equals frameCount (in your test case 61), it will be reset. Since nextFrame() gets called after the Actor's Draw(), the last frame will be drawn and then the currentFrame will be reset back to 1.

Upvotes: 1

Related Questions