Search code examples
javarotationspriteangleslick2d

Can't get sprite to rotate correctly?


I'm attempting to play with graphics using Java/Slick 2D. I'm trying to get my sprite to rotate to wherever the mouse is on the screen and then move accordingly. I figured the best way to do this was to keep track of the angle the sprite is at since I have to multiply the cosine/sine of the angle by the move speed in order to get the sprite to go "forwards" even if it is, for instance facing 45 degrees in quadrant 3.

However, before I even worry about that, I'm having trouble even getting my sprite to rotate in the first place. Preliminary console tests showed that this code worked, but when applied to the sprite, it just kind twitches. Anyone know what's wrong?

int mX = Mouse.getX();
int mY = HEIGHT - Mouse.getY();
int pX = sprite.x;
int pY = sprite.y;
int tempY, tempX;
double mAng, pAng = sprite.angle;
double angRotate = 0;

if (mX != pX) {
    tempY = pY - mY;
    tempX = mX - pX;
    mAng = Math.toDegrees(Math.atan2(Math.abs((tempY)), Math.abs((tempX))));

    if (mAng == 0 && mX <= pX)
        mAng = 180;
}
else {
    if (mY > pY)
        mAng = 270;
    else
        mAng = 90;
}

// Calculations
if (mX < pX && mY < pY) { // If in Q2
    mAng = 180 - mAng;
}
if (mX < pX && mY > pY) { // If in Q3
    mAng = 180 + mAng;
}
if (mX > pX && mY > pY) { // If in Q4
    mAng = 360 - mAng;
}

angRotate = mAng - pAng;
sprite.angle = mAng;
sprite.image.setRotation((float) angRotate);

Solution

  • Firstly, atan2 can get the correct angle for you - just remove Math.abs from the inputs, and you won't need your three four if statements that you use to correct the quadrants of the angle. (Though you have to get the subtractions the right way around)

    Secondly, you're setting the sprite's rotation to mAng - pAng, which amounts to "old angle - new angle". So in reality you're setting the rotation to how much the angle changed since last time (which makes no sense for this purpose), and not the angle itself.

    Combining these suggestions I'd recommend something like this:

    mAng = Math.toDegrees(Math.atan2(mY - pY, mX - pX));
    sprite.angle = mAng;
    sprite.image.setRotation((float) mAng);