I’ve got a problem and I haven’t yet found an explained solution to get it drilled into my head:
I want my object to make a basic rotation TOWARDS the mouse cursor, not the lock-on.
I know it must be embarrassingly easy since there’s not many threads documenting this, yet I’m loosing my mind when seeing (wantedAngle-object.getRotation())
reaching from -180 to 180 degrees.
I’ve tried adding/subtracting 180 or 360 after calculating wantedAngle and reverse it before calculating the desired rotation direction with if-statements like
if(wantedAngle<-0){//turn left applying turnSpeed etc}
as an example
This is the code that I’m stuck with and build tests upon:
void myObject::stareAtMouse(sf::Vector2i mouseLoc)
{
float dx = rect.getPosition().x - mouseLoc.x;
float dy = rect.getPosition().y - mouseLoc.y;
float wantedAngle = atan2(dy,dx) * 180 / M_PI;
cout<<wantedAngle-rect.getRotation()<<endl; //Prints -180 to 180
}
Please tell me how to approach this problem cus I’m losing my mind over this! Are there possibly multiple ways to solve/convert this?
Thanks in advance and sorry for the noobish question
EDIT:
As I thought, I was so overly focused on it and made it more complicated than it was.
I’ve created an offset
before but mistook it for degrees, so obviously it didn’t make any sense.
I’ve now incremented the wantedAngle
by 180 after the atan2-function to even the playing-field for offset
and getRotation()
, then get the offset
from wantedAngle-object.getRotation()
and then use if/else if-statements to see if offset
is less than 0 or greater than 0 to make it rotate respectively.
Thanks for your answers so far, they helped a lot!
--> Only thing to fix now is the offset snapping back into negative once the the mouse is on the object’s right. The object’s rotation doesn’t seem to affect this issue at all.
EDIT_2:
Got everything working now and I’ll post my code here:
void Monster::stareMouse(sf::Vector2i mouseLoc)
{
float dx = monsterShape.getPosition().x - mouseLoc.x;
float dy = monsterShape.getPosition().y - mouseLoc.y;
float currentAngle = monsterShape.getRotation() / 180 * M_PI;
float wantedAngle = (atan2(dy,dx) * 180 / M_PI)+180;
float monsterAngle = monsterShape.getRotation();
float offset = wantedAngle - monsterAngle;
if(offset<-180)offset+=360;
else if(offset>180)offset-=360;
if(offset<0)monsterShape.rotate(-turnSpeed);
else if(offset>0)monsterShape.rotate(turnSpeed);
sf::Vector2f mover;
if(abs(offset)>30)
{
mover.x = cos(currentAngle)*(speed/3);
mover.y = sin(currentAngle)*(speed/3);
}
else
{
mover.x = cos(currentAngle)*speed;
mover.y = sin(currentAngle)*speed;
}
cout<<offset<<endl;
monsterShape.move(mover);
}
Not very well formatted yet, but I got it working perfectly.
if(offset<-180)offset+=360;
else if(offset>180)offset-=360; //Basically going all the way around and stopping
if(offset<0)monsterShape.rotate(-turnSpeed);
else if(offset>0)monsterShape.rotate(turnSpeed); //Rotate in the direction of need
The result is a moving object that moves normally while the target is inside of a cone (30 deg here) in front of the object and once it’s out of ‘vision’, it will slow down to refocus the target which looks quite realistic.
https://youtu.be/zNZmAgDHF8k just to show you how it looks like now 🙂
9
I think the logic you want is:
float angleDifference = wantedAngle-rect.getRotation();
while (angleDifference > 180) angleDifference -= 360;
while (angleDifference < -180) angleDifference += 360;
Next, clamp angleDifference to a certain range so that you’re not rotating by a greater angle than you want to. And finally, rotate your object by angleDifference.
1