SFML community forums
Help => General => Topic started by: lapayo 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:
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:
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:
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 ;)
http://www.youtube.com/watch?v=AoW6Jc_APqE
I hope very much that someone can help me.
Thanks in advance,
Simon
-
I don't understand this:
...+(45/PI)
Deg to Rad conversion should be something like:
(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:
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 ;)
-
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:
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
-
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.
-
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:
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.
http://www.youtube.com/watch?v=EnEamffe7UE
Hope someone can help me :)
Thanks,
Simon
-
Hi,
Here my custom angle function, with a demonstration code for what you want.
This should solve your problem.
#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;
}