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

Author Topic: Set Position Of Sprite Depending On Rotation  (Read 5046 times)

0 Members and 1 Guest are viewing this topic.

SkeleDotCpp

  • Newbie
  • *
  • Posts: 12
    • View Profile
Set Position Of Sprite Depending On Rotation
« on: December 28, 2017, 06:22:01 pm »
I have a bullet sprite, and a character sprite with a gun as a part of it.  When I click, I want the bullet to appear on the end of the gun. This isn't possible for me since the character sprite, changes rotation depending on where the mouse is on the screen.

This would only work if my sprite was rotated at a 0 degree angle.
float x = player.character.getPosition().x + 10;
float y = player.character.getPosition().y - 80;
 

If I changed the rotation, the x and y would not change as they depend on the character's position not rotation.

I have messed a bit with the trigonometry functions(cos, sin) but had no luck.

How would I make the bullet's position depend on the rotation?
I attached both images in case someone needs to look at the dimensions.
Note: Both sprites are scaled down to fit the screen, so the dimensions here aren't the one I am using
CharacterRifle: Scaled down by 0.5
Bullet: Scaled down by 0.03
« Last Edit: December 28, 2017, 06:36:28 pm by SkeleDotCpp »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #1 on: December 28, 2017, 07:04:44 pm »
You said you had no luck trying to use trig, but could you be more specific? What did you try and what wasn't working?

Basically you just need to calculate a relative vector from the origin of your character sprite to the end of the gun, similar to what you have already done in the code you showed us. Then, rotate that vector based on the character's sprite rotation. You can use SFML's Transform class for this if you want to make things easier.
« Last Edit: December 28, 2017, 07:06:25 pm by Arcade »

SkeleDotCpp

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #2 on: December 28, 2017, 07:12:55 pm »
Quote
You said you had no luck trying to use trig, but could you be more specific? What did you try and what wasn't working?

I tried multiplying, adding, subtracting, dividing the position, with sine and cosine, nothing worked out well.

Quote
Basically you just need to calculate a relative vector from the origin of your character sprite to the end of the gun, similar to what you have already done in the code you showed us. Then, rotate that vector based on the character's sprite rotation. You can use SFML's Transform class for this if you want to make things easier.

I am really lost, can you show me a code example of what you mean?

Here is what I have came up with,  but I can't figure out how you would rotate the vector using the transform
sf::Transform rotation;
rotation.rotate(character.getRotation());
float x = character.getPosition().x + 15;
float y = character.getPosition().y - 80;
 
« Last Edit: December 28, 2017, 07:24:54 pm by SkeleDotCpp »

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #3 on: December 29, 2017, 08:54:08 am »
Make the bullet's texture the same size as the player sprite, align it to the gun. Think of the bullet as a layer on top of the player sprite. Then just match their rotations.

If collision detection becomes an issue because of the bigger texture size of the bullet, then just use a different rect for its collision.
« Last Edit: December 29, 2017, 12:19:56 pm by NGM88 »

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #4 on: December 29, 2017, 06:40:40 pm »
Look at the sf::Transform documentation and scroll down to the "Detailed Description" section for an example of how to use it. You are basically missing the step where you pass your point into the transform so that it can be rotated.

Since you are creating a point that has an absolute position (instead of one relative to your character), you may also want to look into using one of the other rotate() overloads that allow you to pass in the center of rotation (which would be the character's origin).

SkeleDotCpp

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #5 on: January 02, 2018, 10:50:19 pm »
I have messed a bit more with the transforms like @Arcade told me, and I have come really close to a solution. But it needs a bit of tweaking.

This works when the bullet sprite is facing 0 degrees. But the bullet sprite seems to rotate relative to a different origin rather than the player's origin.

                //Get points
                float playerR = character.getRotation();
                float playerX = character.getPosition().x;
                float playerY = character.getPosition().y;

                float bulletX = playerX + 15;
                float bulletY = playerY - 80;

                float distX = bulletX - playerX;
                float distY = bulletY - playerY;
               
                //Transforms
                sf::Transform translation;
                translation.translate(distX, distY); //Translate by the distance

                sf::Transform rotation;
                rotation.rotate(playerR, sf::Vector2f(playerX, playerY)); //Give rotation and origin

                sf::Transform transform = translation * rotation; //Combine translartio and rotation into 1 tranform
               
                //I think the problem is here. I am not sure what to pass in as Vector2f.
                sf::Vector2f rotatedVec = transform.transformPoint(sf::Vector2f(playerX, playerY));//Apply transform to vector
 

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #6 on: January 02, 2018, 11:52:30 pm »
How far off is the perceived origin? You can probably simplify your code to something like the following (I'm not able to test anything at the moment, so sorry about possible mistakes):

sf::Vector2f bulletOffset(15, -80);
               
sf::Transform tansform;
tansform.rotate(character.getRotation());
sf::Vector2f newBulletOffset = tansform.transformPoint(bulletOffset);

sf::Vector2f bulletPosition = character.getPosition() + newBulletOffset;
 

Also, make sure the origin of your bullet is set to a good value (probably should be the bottom middle), and that the numbers 15 and -80 are correct.

SkeleDotCpp

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #7 on: January 03, 2018, 09:01:01 pm »
Here is how it looks like with the code above, when I hold LMB and rotate 360 degrees.
The character's origin is in the middle (width/2, height/2). And the bullet's origin is the default, which I think is 0, 0.

Arcade

  • Full Member
  • ***
  • Posts: 230
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #8 on: January 03, 2018, 10:45:53 pm »
It looks like your bullet isn't moving at all. It is simply rotating around its origin (top left), but its starting position isn't moving as the character rotates. Am I interpreting the attached picture correctly? If not, perhaps you can explain more exactly what the bad behavior you are seeing is.

In the last line of the code I provided, you end up with a variable called bulletPosition. You need to actually set the bullet's sprite position to that value. Did you do that?

If you still can't figure out your problem, perhaps you could show a more complete (but minimal) example of how you are setting your character and bullet positions and rotations. It's hard to guess what could be going wrong without seeing code.
« Last Edit: January 03, 2018, 11:01:11 pm by Arcade »

SkeleDotCpp

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Set Position Of Sprite Depending On Rotation
« Reply #9 on: January 04, 2018, 08:34:54 pm »
The bullets do move, I just commented out the line that moves them so that you can see where they're being drawn. And the rotation isn't the issue either. The issue here is that they're drawn around that point as origin, while they're supposed to be drawn around the player's origin.

What you see in the image is when my character rotates 360 degrees around himself(Full rotation while standing in one position).

I have tested it again, but this time I actually used your way and it worked exactly how I wanted. No more struggles, thank you :D