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

Author Topic: Problem with moving/turning a sprite in cursor direction  (Read 3085 times)

0 Members and 1 Guest are viewing this topic.

lapayo

  • Newbie
  • *
  • Posts: 8
    • View Profile
Problem with moving/turning a sprite in cursor direction
« on: November 30, 2011, 09:54:09 pm »
Hello SFML-Communiy,
I have a problem which makes me go crazy.

I try to move and turn a sprite in the direction of the cursor.
But it isn´t working very well.
The turning is almost working. But when i start moving the sprite the turning fails. (I think the center is moving or something like that :()

The code for turning looks like the following:

Code: [Select]
float dx = App->GetInput().GetMouseX() - (playerPos.x - player.GetCenter().x);
float dy =  App->GetInput().GetMouseY() - (playerPos.y - player.GetCenter().y);

angle = atan2(dy, dx) + (45/PI);

player.SetRotation(-angle * 180 / PI );

This works not perfect, because for some reason the cursor is not in the middle of the sprite when I turn it to the left for example.


The code for the moving i use just looks like the following:
Code: [Select]
player.Move(-distance, 0);
So moving doesn´t do anything special yet.

The code I tried for moving in the cursor direction was the following:
Code: [Select]
float dY = sin(angle) * distance;
float dX = cos(angle) * distance;


this->player.Move(dX, dY);

where angle is the rotation of the player an distance the distance the sprite should move in the angle direction.

For a better understanding i also produced a little youtube video ;)




I hope very much that someone can help me.

Thanks in advance,

Simon

julen26

  • Jr. Member
  • **
  • Posts: 89
    • View Profile
    • http://julen26.blogspot.com
Problem with moving/turning a sprite in cursor direction
« Reply #1 on: November 30, 2011, 10:39:31 pm »
I don't understand this:
Code: [Select]
...+(45/PI)
Deg to Rad conversion should be something like:
Code: [Select]
(deg * PI) / 180
atan2 function returns the angle in radians, and you are adding some strange value to it. Maybe you have reasons to do it, but I can't deduce more from that piece of code.

Also, I suppose that the center of the sprite is on the middle of the image, so you could simply use this:
Code: [Select]
float dx = App->GetInput().GetMouseX() - playerPos.x;
   float dy =  App->GetInput().GetMouseY() - playerPos.y;


Hope it'll be helpful, if not, do the code more specific.
Nice idea showing a video ;)

lapayo

  • Newbie
  • *
  • Posts: 8
    • View Profile
Problem with moving/turning a sprite in cursor direction
« Reply #2 on: November 30, 2011, 10:44:47 pm »
Thanks for the reply :)
The 45/PI was for adding 90 degress to the angle. It was a quick and dirty hack i tried because the rotation of the sprite had a wrong offset  :D

And the center isn´t the spritepos always the upper left corner?
So with:
Code: [Select]
float dx = App->GetInput().GetMouseX() - playerPos.x;
I would just get the difference from the upper left corner to the cursor, but i want the center to move in the cursors direction.

I hope it was understandable and you can help me better now :)


Thanks,

Simon

Serapth

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Problem with moving/turning a sprite in cursor direction
« Reply #3 on: December 01, 2011, 02:45:15 am »
Quote from: "lapayo"
Thanks for the reply :)
The 45/PI was for adding 90 degress to the angle.



45/pi is 14.3 ( or a meaningless number in radians )

90 degrees is pi/2 or 1.57 radians.



EDIT: As you have expressed things, 14.3 radians is 819.3 degrees.  So I suppose once translated back to an angle that will become ( I am guessing here, 819.3%360 ) or 99.3 degrees, which is why your code *kinda* works, even though it is logically wrong, by happy coincidence, your odd ball value is resolving reasonably close to the value you want.

lapayo

  • Newbie
  • *
  • Posts: 8
    • View Profile
Problem with moving/turning a sprite in cursor direction
« Reply #4 on: December 01, 2011, 02:23:51 pm »
Thanks for your reply :)

I think I remembered something wrong with the 45/PI :D

But PI/2 are working fine I think.

But there still seams to be a problem with the center wenn the Sprite changes his position.

I got the following code:

Code: [Select]
float dx = App->GetInput().GetMouseX() - (playerPos.x - player.GetCenter().x);
float dy =  App->GetInput().GetMouseY() - (playerPos.y - player.GetCenter().y);

angle = atan2(dy, dx) + (PI/2);

player.SetRotation(-angle * 180 / PI);


But dx and dy are 0 when the mouse is far away from the position of the sprite.
Where is my mistake?

I also uploaded a video again, where everyone can see, how far the position is away.


Hope someone can help me :)


Thanks,

Simon

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Problem with moving/turning a sprite in cursor direction
« Reply #5 on: December 02, 2011, 02:24:36 am »
Hi,

Here my custom angle function, with a demonstration code for what you want.
This should solve your problem.

Code: [Select]
#include <cmath>
#include <SFML/Graphics.hpp>

#define PI 3.14159265f

// return angle between 2 points (radians)
float angle(const sf::Vector2f& p1, const sf::Vector2f& p2)
{
float x = p1.x - p2.x;
if (x == 0.f)
{
return 0.f;
}
float y = p1.y - p2.y;
float radians = std::atan(-y / x);
if (p2.x > p1.x)
{
radians += PI;
}
return radians;
}

// convert radians to degrees
float rad_to_deg(float radians)
{
return radians / PI * 180;
}


int main()
{
sf::RenderWindow app(sf::VideoMode(640, 480, 32), "SFML Window");
sf::Event event;
bool running = true;

sf::Image img;
img.LoadFromFile("images/arrow.png");

// create arrow, centered on screen
sf::Sprite arrow(img);
arrow.SetCenter(img.GetWidth() / 2, img.GetHeight() / 2);
arrow.SetPosition(320, 240);

while (running)
{
while (app.GetEvent(event))
{
if (event.Type == sf::Event::Closed)
{
running = false;
}
else if (event.Type == sf::Event::MouseMoved)
{
sf::Vector2f mouse(event.MouseMove.X, event.MouseMove.Y);
float mouse_angle = rad_to_deg(angle(arrow.GetPosition(), mouse));
arrow.SetRotation(mouse_angle);
}
}

app.Clear();
app.Draw(arrow);
app.Display();
}
app.Close();

return 0;
}