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

Author Topic: How to do Real Animation in C++ SFML  (Read 18764 times)

0 Members and 1 Guest are viewing this topic.

amanuel2

  • Newbie
  • *
  • Posts: 4
    • View Profile
How to do Real Animation in C++ SFML
« on: May 21, 2016, 07:21:42 pm »
im kinda confused on how the animation works in SFML.. So ima try to explain where i am at and where i am confused. So Right now this is the full sprite:



As you can see above those are the sprites.. Here is the code i currently have:


    #include <SFML/Graphics.hpp>
    #include <time.h>
    #include <string>
    #include <iostream>
   
    #define SPRITE_WIDTH 32
    #define SPRITE_HEIGHT 32
    #define DIRECTION_Y_DOWN_INITAL 0
    #define DIRETION_Y_LEFT_INITAL 1
    #define DIRECTION_Y_RIGHT_INITAL 2
    #define DIRECTION_Y_UP_INITAL 3
   
    #define DIRECTION_X_DOWN_INITAL 0
    #define DIRECTION_X_LEFT_INITAL 0
    #define DIRECTION_X_RIGHT_INITAL 0
    #define DIRECTION_X_UP_INITAL 0
   
   
    using std::cout;
    using std::endl;
   
   
    class Mouvment
    {
    public:
        Mouvment() {};
   
        void goDirection(const int &dir, sf::Sprite &spritesheet)
        {
                switch (dir) {
                case 0:
                        spritesheet.move(sf::Vector2f(0, -3));
                        break;
                case 1:
                        spritesheet.move(sf::Vector2f(0, 3));
                        break;
                case 2:
                        spritesheet.move(sf::Vector2f(3, 0));
                        break;
                case 3:
                        spritesheet.move(sf::Vector2f(-3, 0));
                        break;
                }
        }
    };
   
    int main()
    {
        sf::RenderWindow _window(sf::VideoMode(600, 600), "Hello World");
        sf::Texture _texture;
        sf::Vector2i source(DIRECTION_X_DOWN_INITAL, DIRECTION_Y_DOWN_INITAL);
        Mouvment mouvment;
        if (!(_texture.loadFromFile("Resources/SPRITE.png")))
        {
                cout << "Could Not Load File.." << endl;
        }
   
        sf::Sprite _sprite;
        _sprite.setTexture(_texture);
   
        while (_window.isOpen())
        {
                sf::Event _event;
                while (_window.pollEvent(_event))
                {
                        switch (_event.type)
                        {
                        case sf::Event::Closed:
                                _window.close();
                                exit(1);
                        case sf::Event::KeyPressed:
                                switch (_event.key.code)
                                {
                                case sf::Keyboard::Right:
                                        mouvment.goDirection(2, _sprite);
                                        source.x = DIRECTION_X_RIGHT_INITAL;
                                        source.y = DIRECTION_Y_RIGHT_INITAL;
                                        break;
                                case sf::Keyboard::Left:
                                        mouvment.goDirection(3, _sprite);
                                        source.x = DIRECTION_X_LEFT_INITAL;
                                        source.y = DIRETION_Y_LEFT_INITAL;
                                        break;
                                case sf::Keyboard::Up:
                                        mouvment.goDirection(0, _sprite);
                                        source.x = DIRECTION_X_UP_INITAL;
                                        source.y = DIRECTION_Y_UP_INITAL;
                                        break;
                                case sf::Keyboard::Down:
                                        mouvment.goDirection(1, _sprite);
                                        source.x = DIRECTION_X_DOWN_INITAL;
                                        source.y = DIRECTION_Y_DOWN_INITAL;
                                        break;
                                }
                                break;
                        }
                }
                _sprite.setTextureRect(sf::IntRect(source.x * SPRITE_WIDTH , source.y * SPRITE_HEIGHT , SPRITE_WIDTH, SPRITE_HEIGHT));
                _window.draw(_sprite);
                _window.display();
                _window.clear();
        }
    }
 

So right now my code currently operates in the first row of the Spritesheet. It can do Down , Up, Left, and Right direction BUT ONLY for the first row.. Is there a way to do it so if i press right key, it cycles through three of the rows in the first column so it actually looks like the character is Walking? Thankyou, btw im watching this [tutorial][2].


  [2]:

amanuel2

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How to do Real Animation in C++ SFML
« Reply #1 on: May 21, 2016, 08:06:25 pm »
For some reason this works:
                source.x++;
                if (source.x * 32 >= _texture.getSize().x)
                        source.x = 0;
 

But i dont understand why! And i want to understand why so i can apply it in my future SFML Programming..

Erdrick

  • Jr. Member
  • **
  • Posts: 61
    • View Profile
    • Email
Re: How to do Real Animation in C++ SFML
« Reply #2 on: May 21, 2016, 10:53:33 pm »
Hi amanuel2,

The sprite sheet you are working is 3x4, so there are 3 animation frames for each direction and 4 directions.

Row 1 are the walking down frames
Row 2 are the walking left frames
Row 3 are the walking right frames
Row 4 are the walking up frames

The screen coordinate system is different than the cartesian coordinate system you may have learned in math.  X still increases as you go right but Y increases as you go DOWN.

When you are checking the keyboard for the direction pressed, it is setting source.x and source.y.  X is always set to 0 in the switch statement so it will start with the first frame for that direction.  Y is set to 0,1,2, or 3 to pick the row for the appropriate direction.

When you  call  _sprite.setTextureRect at the bottom you are "isolating" the first frame for the direction you chose for display purposes.

To get to the next frame for that direction, you need the second piece of code you wrote


source.x++;                                                      

// This line increased X from 0 to 1
// This means that the next time you call
// setTextureRect it will pass 1*SPRITE_WIDTH
// instead of 0xSPRITE_WIDTH.  This has the effect
// of picking the frame 32 pixels to the right which is
// essentially the next frame of that direction.

if (source.x * 32 >= _texture.getSize().x)

// Once the multiplication produces a number of pixels
// that is greater than the size of the texture, that means
// it has already gone through all of the frames for that
 // direction and needs to start at 0 again for the first frame
                                                                                   
            source.x = 0;

 

amanuel2

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: How to do Real Animation in C++ SFML
« Reply #3 on: May 22, 2016, 04:51:32 am »
Ok Erdrick! Thanks for that! But one question.. I dont know how to change the program so that when the user dosent click any controls, it just dosent go on running state.. But as soon as he does it starts to actually show the running motion. Any ideas on how to acomplish that?

Erdrick

  • Jr. Member
  • **
  • Posts: 61
    • View Profile
    • Email
Re: How to do Real Animation in C++ SFML
« Reply #4 on: May 22, 2016, 05:22:45 am »
Ok Erdrick! Thanks for that! But one question.. I dont know how to change the program so that when the user dosent click any controls, it just dosent go on running state.. But as soon as he does it starts to actually show the running motion. Any ideas on how to acomplish that?

For this, you will need to wrap the logic below in an if condition.  This if condition will need to check if the user is pressing the keyboard buttons again and only do this logic if one of those four keyboard buttons is being pressed.

        source.x++;
        if (source.x * 32 >= _texture.getSize().x)
            source.x = 0;
 

The condition you write for this will be separate from the event logic above.  Please read the SFML tutorials on this site to understand the difference between Events and Real Time Inputs

Once you have read these two topics thoroughly and understand them, you will know why Events and Real Time Inputs are different.

  • Events explained
  • Keyboard, mouse and joysticks

You are making good progress on your learning, but doing the tutorials in order on this site is also very beneficial!

 

anything