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

Author Topic: Sprite rotation on tile map [FIXED]  (Read 2047 times)

0 Members and 1 Guest are viewing this topic.

BlockyNewt

  • Newbie
  • *
  • Posts: 4
    • View Profile
Sprite rotation on tile map [FIXED]
« on: July 14, 2020, 06:04:15 pm »
[FIXED]
-Read below for answer.

I've been searching around for a solution for hours now and I still haven't managed to find anything. I've also looked at https://www.sfml-dev.org/tutorials/2.5/graphics-transform.php.

The problem...
I have a 11x11 tile map with each tile being 125x125. I would like to rotate my sprite which is also 125x125, but it goes off center unless its in the first tile of the tilemap.

To put it simple, I click a tile and then press 'Q' to rotate it, but the origin is off. How can I set the origin correctly with a tile map?

void Player::initializePlayer(const sf::Texture& idle_T)
{      
        this->player_Sprite.setTexture(this->idle_T);
        this->player_Sprite.setTextureRect(*this->idle_Frame);
        this->player_Sprite.setPosition(sf::Vector2f(0.f, 0.f));
        this->player_Sprite.setOrigin(sf::Vector2f(125.f, 125.f));
}
 

void Player::updatePollEvent(sf::Event& ev, const sf::Vector2f& tilePosition)
{
        if (ev.type == sf::Event::KeyPressed)
        {
                if (ev.key.code == sf::Keyboard::Q)
                {
                        this->transform.rotate(10.f);
                }
        }

        this->player_Sprite.setOrigin(sf::Vector2f(
                this->player_Sprite.getLocalBounds().width / 2.f,
                this->player_Sprite.getLocalBounds().height / 2.f));
}
 
I tried passing the tile's position here to set the origin but that did not work either.

My first post and I'm sorry if the post is not up to standards with the rules. Any help would be much appreciated.

[SOLUTION]
-Rotate the sprite directly using
sprite.rotate(x.f)
and also draw the sprite directly
target.draw(sprite)
instead of
target.draw(sprite, transform)
« Last Edit: July 15, 2020, 06:42:05 am by BlockyNewt »

Stauricus

  • Sr. Member
  • ****
  • Posts: 369
    • View Profile
    • A Mafia Graphic Novel
    • Email
Re: Sprite rotation on tile map
« Reply #1 on: July 14, 2020, 06:59:25 pm »
it could be because you are constantly reseting the sprite origin when you update poll events.
have you tried like this?
void Player::initializePlayer(const sf::Texture& idle_T)
{      
//[...]
        this->player_Sprite.setOrigin(sf::Vector2f(
                this->player_Sprite.getLocalBounds().width / 2.f,
                this->player_Sprite.getLocalBounds().height / 2.f));
}
Visit my game site (and hopefully help funding it? )
Website | IndieDB

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Sprite rotation on tile map
« Reply #2 on: July 14, 2020, 09:12:31 pm »
You want to match the sprite's position to the position it would've been inside the tile map after the tile map has been rotated?

Determine the position in the tile map that the sprite should be before rotation of the tile map and then use the tile map's transform to transform that point to where it will actually be when drawn.

Assuming that the sprite position would be (3, 3) of the tile map at each being 125x125, its "unlinked" position would be (3x125, 3x125) = (375, 375) and therefore it could be something like:
sf::Vector2f spriteLocalPosition{ 375.f, 375.f };
sf::Vector2f spriteGlobalPosition{ tilemap.getTransform().transformPoint(spriteLocalPosition) };

Remember that it's the local position within the tile map so position/translation, scaling etc. of the tilemap should not be included in the local sprite position.

If you need to find the local position of its current position, you can do the opposite process:
sf::Vector2f currentSpriteGlobalPosition{ 500.f, 500.f };
sf::Vector2f currentSpriteLocalPosition{ tilemap.getInverseTransform().transformPoint(currentSpriteGlobalPosition) };

You may want to use that in conjunction with the first one to "move" with the tile map (this bit would be first).
« Last Edit: July 14, 2020, 09:15:19 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

BlockyNewt

  • Newbie
  • *
  • Posts: 4
    • View Profile
Re: Sprite rotation on tile map
« Reply #3 on: July 14, 2020, 11:47:04 pm »
it could be because you are constantly reseting the sprite origin when you update poll events.
have you tried like this?
void Player::initializePlayer(const sf::Texture& idle_T)
{      
//[...]
        this->player_Sprite.setOrigin(sf::Vector2f(
                this->player_Sprite.getLocalBounds().width / 2.f,
                this->player_Sprite.getLocalBounds().height / 2.f));
}

Same results.

You want to match the sprite's position to the position it would've been inside the tile map after the tile map has been rotated?

I would like the sprite to match with the tile position when rotating.

While on the first tile it rotates fine, but moving to another then rotating makes it move rotate around in a circle.

For more of a visual representation here is a video.

« Last Edit: July 14, 2020, 11:48:46 pm by BlockyNewt »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Sprite rotation on tile map [FIXED]
« Reply #4 on: July 20, 2020, 10:35:47 pm »
If a sprite it rotate around its center, its origin should be its local center.

draw the sprite directly
target.draw(sprite)
instead of
target.draw(sprite, transform)
You were passing a transform to the draw method as well as transforming the sprite directly (setPosition etc.)?
I don't think you mentioned this :P
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*