SFML community forums

Help => Graphics => Topic started by: ka0s420 on January 11, 2017, 10:27:32 pm

Title: rotating sprite without using transform.rotate
Post by: ka0s420 on January 11, 2017, 10:27:32 pm
Okay, so my game uses a grid, pathfinding etc, i.e agents are stuck down to definite integer coordinates and can't just roam freely. To cut down on having to make a ton of artwork (and because the game is orthogonal/top down)  I decided it would be easier to use pure top down sprites and simply rotate them, effectively making it so I only needed to make artwork for one walk cycle, idle, attack etc.

However sadly I can't get rotation to work because of changing the origin. Now I've seen much discussion stating that if you want to keep the origin in the top left I would need to use a transform object and apply rotation to that and use it as a renderstate, however I couldn't get that to work. The main reason being that the transform only has transform.rotate, whereas the formula i use to work out rotation outputs an angle which is only good for sprite.setRotation as it sets the absolute rotation as opposed to the relative one.

So what I decided to try and do was to try various means of changing the the sprite's origin, set the rotation and then set the origin back to the left top corner, however this still produces undesirable outcomes. Here's my latest attempt at that. I used the hardcoded number 16 for ease of use and my sprites are 32x32, so it's their centre point:

void Entity::handleRotation(Tile * target)
{
        setOrigin(16, 16);
        setPosition(getPosition().x + 16, getPosition().y + 16);
        float angle = atan2(target->getPosition().y - getPosition().y, target->getPosition().x - getPosition().x);
        angle = ((angle * 180) / 3.14159265) + 90;
        {
                angle = 360 - (-angle);
        }
        setRotation(angle);
        setOrigin(0, 0);
        setPosition(getPosition().x - 16, getPosition().y - 16);
}


Again, this hasn't done as expected and I've tried many variants to no effect  :-\ Any suggestions, explanations or examples would be extremely helpful. Thanks in advance ;)

*note setOrigin, setPosition, getPosition,  setRotation are usable because the entity class publicly inherits from sprite.
Title: Re: rotating sprite without using transform.rotate
Post by: eXpl0it3r on January 11, 2017, 10:58:19 pm
So why do you not simply set the origin to the center of the sprite and call setRotation?
You want your character to spin around its axis and not spin around its top-left corner, don't you?
Title: Re: rotating sprite without using transform.rotate
Post by: ka0s420 on January 11, 2017, 11:04:20 pm
When i Just set the origin to the centre and leave it there, the sprite is no longer lined up with the grid spacing, so the sprite is always on the edge of each tile, instead of in the middle of it like it should be.
Title: Re: rotating sprite without using transform.rotate
Post by: eXpl0it3r on January 11, 2017, 11:17:07 pm
Ah okay, I misunderstood you then. :)

What were the undesirable outcomes if you just change the origin, rotate and change back?

Did you derive from sf::Sprite or sf::Transformable?
Title: Re: rotating sprite without using transform.rotate
Post by: ka0s420 on January 11, 2017, 11:24:21 pm
hmm, well changing the origin to the centre, rotating and then changing it back to 0, 0, made it so the sprite is following the path, but off to the side of the path. The class inherits from sf::Sprite.

here is a screenshot for further clarification:

https://www.dropbox.com/s/za6cs8uk0853zbi/fail.png?dl=0 (https://www.dropbox.com/s/za6cs8uk0853zbi/fail.png?dl=0)

in the picture, the green squares are the path that the entity should be walking along, and even though it is following them, it is drawn off to the side. I put a circle around the moving entity so you can see what i mean.
Title: Re: rotating sprite without using transform.rotate
Post by: ka0s420 on January 12, 2017, 12:51:29 am
Okay, well it's perhaps not the ideal way of doing things, particularly as my entity class already inherited from sf::Sprite, but I basically just instantiated another sprite as a member of entity and swapped something around so that it is used for the animations and drawing. That way I can use the inherited sprite for all the movement calculations and then use the instantiated mSprite to draw with an offset and so now it looks the way it should.

Solved I guess.