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

Author Topic: My SpriteSheet only animates faces to the right, and if I want it to left animat  (Read 2186 times)

0 Members and 1 Guest are viewing this topic.

hdsiria

  • Newbie
  • *
  • Posts: 23
    • View Profile
My SpriteSheet only animates faces to the right, and if I want it to left animation, I have to detect the sprite direction every time the Sprite is updated,and  using transfrom,animation from right to left, but my cpu usage increased by 2%. Is there a better way?
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const{
                states.transform *= getTransform();
                //if sprite orientation left
                if (m_spriteOrientation == SpriteOrientation::LEFT){
                        //set Origin
                        m_sprite->setOrigin(sf::Vector2f(m_sprite->getLocalBounds().width - m_sprite->getOrigin().x, 0));
                        //Horizontal flip,sprite face to left
                        m_sprite->scale(-1.f, 1.f);

                }
                //draw sprite
                target.draw(*m_sprite, states);

                //if sprite orientation left
                if (m_spriteOrientation == SpriteOrientation::LEFT){
                        //Flip back,sprite face to right
                        m_sprite->scale(-1.f, 1.f);
                        //Restore Origin
                        m_sprite->setOrigin(sf::Vector2f(0, 0));
                }

        }
 


Seim2k

  • Newbie
  • *
  • Posts: 3
    • View Profile
Hi,

somewhere i read you shouldn't use scale, but setScale(x,y). You could also check before you flip and don't set the scale in every timeframe.

In my project i did st like this (it' s also executed in an update loop)

void SpritesheetAnimation::flipAnimationLeft() {
    if (mSprite.getScale().x != -1) {
        // do not ever use mSprite.scale({x,y}) !!!
        mSprite.setScale({-1, 1});
    }
}

void SpritesheetAnimation::flipAnimationRight() {
    if (mSprite.getScale().x != 1) {
        // do not ever use mSprite.scale({x,y}) !!!
        mSprite.setScale({1, 1});
    }
}
 

And at the appropriate location in the code:

    if(event.type == sf::Event::KeyPressed)
    {
        switch (event.key.code)
        {
            case sf::Keyboard::D:
            case sf::Keyboard::Right:
            {
                playerCharacter->handleInput(EInput::PressRight);
                playerCharacter->getSpriteAnimation().flipAnimationRight();
                playerCharacter->setMoveDirection(EMoveDirection::Right);
                break;
            }

            case sf::Keyboard::A:
            case sf::Keyboard::Left:
            {
                playerCharacter->handleInput(EInput::PressLeft);
                playerCharacter->getSpriteAnimation().flipAnimationLeft();
                playerCharacter->setMoveDirection(EMoveDirection::Left);
                break;
            }
 
« Last Edit: November 24, 2023, 12:28:36 pm by Seim2k »

hdsiria

  • Newbie
  • *
  • Posts: 23
    • View Profile
Oh, thanks

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
somewhere i read you shouldn't use scale, but setScale(x,y).
scale just calls setScale after two simple multiplications so scale isn't inherently bad.

don't set the scale in every timeframe.
This is the important point here, I think. scaling (setting absolutely or relatively) causes the transform and geometry to require an update, which could be avoided. However, I don't think it's significant to worry about unless you have very many sprites.

my cpu usage increased by 2%. Is there a better way?
Is 2% CPU increase really an issue? Does it affect the performance of your program? Are you running debug or release mode when measuring? Are you running from an IDE/builder or directly from an executable file? These can all affect measurements along with numerous other things. :P
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

hdsiria

  • Newbie
  • *
  • Posts: 23
    • View Profile
I am running the program in debug mode, and I know that debug mode takes up more cpu. But calculating transformations on every frame i think is an inefficient approach. Why waste cpu on this?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
But calculating transformations on every frame i think is an inefficient approach.
Calculating transformations can be expensive, yes, but the actual transformation calculations are not made until you draw it - and it's done by the graphics card*. All you're really doing when you change position, scale or rotation of an sf::Transformable (such as an sf::Sprite), is changing a few floats by adding or multiplying, which is very insignificant. Obviously, you can do many thousands or millions of these calculations every frame.

I would also say that testing memory or speed using debug is not the best option. It's up to the debugger to decide how much memory it wants to use to track the things it's doing and speed can be affected by debugging processes.
Try release mode and see if you have an issue.


*Usually. You can, of course, do CPU-based transformations calculations as well. For matrix transformations, see sf::Transform.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

hdsiria

  • Newbie
  • *
  • Posts: 23
    • View Profile
I think you're right.master.
I tried the comparison again and found no increase in cpu usage, I don't know why maybe I got the wrong comparison earlier.
I don't have to change it if it doesn't take up too much cpu after drawing a lot of sprites. It seems inefficient, but it's not worth mentioning for modern hardware, is it?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
As a bonus, if you're drawing lots of separate sprites, consider this, which I recently created to automatically (and very simply) batch sprites into a single draw call:
https://en.sfml-dev.org/forums/index.php?topic=29286.0 (Simple Sprite Batcher on SFML forum)
 ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*