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

Author Topic: SFML 2.0 Sprite animation  (Read 13728 times)

0 Members and 1 Guest are viewing this topic.

GroundZero

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
SFML 2.0 Sprite animation
« on: August 26, 2011, 08:18:58 pm »
Hey all,

I am trying to get my sprite to walk left or right. I am using 5 images.

Image 1 = standing still.
Image 2 till 5 are running animations.

What I need to accomplice is:

if no button left or right is pressed display 1.
If left or right is pressed start with 2, then 3, then 4, then 5.
Then go back to 4, then 3, then 2, and now repeat the process. THis way I would have a smooth animation of my character running.

I have been trying it my self for a couple of days now, I also tried some stuff from YouTube today for like 8 hours but I just cant get it to work.

Can someone please write me a example code? or just give me a couple of directions? I dont know either if I should write a class for my character or not. Any information would be highly appreciated!

Ill post my current code down here.

Have a nice weekend!

Yours sincerely,

GZ

P.S. My char is movable (left and right) as you can see, but I have not written the whole setTexture codes yet cause I keep failing at them. I need them in the sequence of 2, 3, 4, 5, 4, 3, 2 and so on...

Currently I wrote a couple when walking left but it does not change the animation. It only uses frame 2 then it gets stuck at frame 1 it seems.


Code: [Select]
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Config.hpp>

// set some globals
char faceDirection = 'L';     // L = Left, R = Right
int minAni = 2;               // Start at picture 2 for the walk animation
int maxAni = 5;               // End at picture 5 for the walk animation
int curAni = 2;               // What animation we start on
char wayAni = 'R';            // What way should we start counting first

int main()
{
    // create a new window 800x600 resolution 32 bit
    sf::RenderWindow App(sf::VideoMode(800, 600, 32), "MyTest");


    /////////////////////////////////// SPRITE 1 FRAME 1 //////////////////////
    sf::Image character1;
    character1.LoadFromFile("character_sprites/character_1.png");

    sf::Texture charTexture1;
    charTexture1.LoadFromImage(character1);

    sf::Sprite charSprite1(charTexture1);
    charSprite1.SetPosition(390, 400);

    /////////////////////////////////// SPRITE 1 FRAME 2 //////////////////////
    sf::Image character2;
    character2.LoadFromFile("character_sprites/character_2.png");

    sf::Texture charTexture2;
    charTexture2.LoadFromImage(character2);

    /////////////////////////////////// SPRITE 1 FRAME 3 //////////////////////
    sf::Image character3;
    character3.LoadFromFile("character_sprites/character_3.png");

    sf::Texture charTexture3;
    charTexture3.LoadFromImage(character3);

    /////////////////////////////////// SPRITE 1 FRAME 4 //////////////////////
    sf::Image character4;
    character4.LoadFromFile("character_sprites/character_4.png");

    sf::Texture charTexture4;
    charTexture4.LoadFromImage(character4);

    /////////////////////////////////// SPRITE 1 FRAME 5 //////////////////////
    sf::Image character5;
    character5.LoadFromFile("character_sprites/character_5.png");

    sf::Texture charTexture5;
    charTexture5.LoadFromImage(character5);

    //////////////////////////////////////////////////////////////////////////


    // timers so app runs on the same speed on every machine possible
    sf::Clock clock;        // timer for events
    sf::Clock aniClock;     // timer for character animation

    while( App.IsOpened())
    {
        // events loop
        sf::Event Event;
        while (App.PollEvent(Event))
        {
            switch(Event.Type)
            {
                // if screen is closed
                case sf::Event::Closed:
                    App.Close();
                break;
            }

        } // end events

        // move the character at a rate of 33 ms per second
        if(clock.GetElapsedTime() >= 33)
        {
            if(sf::Keyboard::IsKeyPressed(sf::Keyboard::Left))
            {
                charSprite1.Move( -2, 0 );
            }

            if(sf::Keyboard::IsKeyPressed(sf::Keyboard::Right))
            {
                charSprite1.Move( 2, 0 );
            }

            // reset the clock for the event timer
            clock.Reset();
        }



        if(aniClock.GetElapsedTime() >= 100)
        {

            if(sf::Keyboard::IsKeyPressed(sf::Keyboard::Left))
            {
                // check if facing the opposit side then flip
                if( faceDirection == 'R')
                    charSprite1.FlipX(false);

                // set the direction we are facing
                faceDirection = 'L';

                // set to frame 2
                if( curAni <= 2 && wayAni == 'R')
                    charSprite1.SetTexture(charTexture2);
                curAni++;

                // set to frame 3
                if( curAni <= 3 && wayAni == 'R')
                    charSprite1.SetTexture(charTexture3);
                curAni++;

                // set to frame 4
                if( curAni <= 4 && wayAni == 'R')
                    charSprite1.SetTexture(charTexture4);
                curAni++;

                // set to frame 5 and set the wayAni in the opposite way
                if( curAni <= 5 && wayAni == 'R')
                    charSprite1.SetTexture(charTexture5);
                curAni++;
                wayAni = 'L';

            }
            else if(sf::Keyboard::IsKeyPressed(sf::Keyboard::Right))
            {
                // check if facing the opposit side then flip
                if( faceDirection == 'L')
                    charSprite1.FlipX(true);

                // set the direction we are facing
                faceDirection = 'R';
            }
            else
            {
                // we are not moving, set the sprite back to animation 1
                charSprite1.SetTexture(charTexture1);
            }

            aniClock.Reset();

        }




        // clear the screen
        App.Clear();

        // draw the sprite
        App.Draw(charSprite1);

        // display the window with the new stuff
        App.Display();

    } // end while App is opened

    return EXIT_SUCCESS;
}

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
SFML 2.0 Sprite animation
« Reply #1 on: August 26, 2011, 11:28:30 pm »
Heyho,

I just took a fast look at your code and I didn't concentrait mch on the animation part, but I've got some tips about handling the images.
You probably started your project before the API change of sf::Image and sf::Texture or you didn't understand how it was meant.
Because you load an sf::Image and the convert it into a sf::Texture, and never use the image ever gain. But sf::Texture has the method 'LoadFromFile' too, so you won't have to bother with sf::Image.
Code: [Select]
sf::Texture charTexture1;
charTexture1.LoadFromFile("character_sprites/character_1.png");


Next rather then having x textures variable I would either recommend an array (or STL std::vector) or you use just one image/texture and use the SubRect of the sprite to define which sector gets displayed (and optimizes your memory usage). You then would have to deal with just one sprite and one texture (or more if you decide to split for left/right movement for example).

For the animation part I didn't take the time to verify your code. But yes it's a very good idea to create a class. There are many ways to do it.
Nexus would now advise you to use thor::Animation or have a good look at it. I hadn't have time to do so myself, but I know his code is (mostly) pretty neat! :wink:
Website to the Thor library - Complete animation example

Animation is at the moment also discussed here.

eXpl0it3r
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
SFML 2.0 Sprite animation
« Reply #2 on: August 27, 2011, 03:44:41 am »
Thanks a lot for the trust in Thor ;)

However I have to say that the functionality in the Animation module is rather limited at the moment. You can currently add frames (with sub-rects and textures) to an animation and assign different display times to them, e.g. like this:
Code: [Select]
thor::FrameAnimation anim;
anim.AddFrame(2.3f, sf::IntRect(...));
anim.AddFrame(1.f, sf::IntRect(...));

One of the things I plan to add is often-needed functionality like reversed, looped or concatenated animations. This might help here, too. When you have ideas or concrete proposals, don't hesitate to inform me in the Thor thread :)

Back to topic: Generally, it pays off fast to outsource and generalize functionality. That is, instead of hardcoding the animations for this specific use case, write classes and functions that take care of the boilerplate code. Like this, you can just reuse the code if you have another animation. And the code complexity suddenly shrinks.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

GroundZero

  • Jr. Member
  • **
  • Posts: 69
    • View Profile
SFML 2.0 Sprite animation
« Reply #3 on: August 27, 2011, 01:08:00 pm »
I never used THOR before, just got into SFML lol ill look into it thanks guys!