Smooth Player Rotation

Does anyone know if there is an easy way to smooth out rotation angle, to achieve a smooth player rotation?

playerAngle = Phaser.Math.Angle.RotateTo(CurrentplayerAngle, TargetAngle, 0.03);

I am trying to tween the SpeedValue (0.03) but i’m not having much luck.

Cheers for any help.

That’s the right method. It needs to be called repeatedly. And usually you would reassign the same value.

playerAngle = Phaser.Math.Angle.RotateTo(playerAngle, TargetAngle, 0.03);

What is happening? Wrong rotation or no rotation?

Hey thanks.
I have been trying to solve this now for two days and its doing my head in…

I went away from that method above because while I sussed out how to accelerate the player rotation in the direction of the mouse, I struggled to work out when to Start a Decelerate.

Also that the tween doesn’t keep restarting when the mouse is moved.

So then I tried something else.

This results in Smooth Rotation until it hits -180 / 180 then bounces…

Tween in Create

AngleTween = this.tweens.add({
targets: player,
angle: 0,
ease: ‘Sine.easeInOut’,
duration: 400,
});

Then in Update

var PlayerPosX = player.body.position.x
var PlayerPosY = player.body.position.y
var MousePosX = this.cameras.main.scrollX + game.input.mousePointer.x;
var MousePosY = this.cameras.main.scrollY + game.input.mousePointer.y;

var RotTargetAngle_RADS = (Phaser.Math.Angle.Between(PlayerPosX, PlayerPosY, MousePosX, MousePosY));
var RotTargetAngle_DEGS = parseInt(RadToDeg(RotTargetAngle_RADS));

var playerAngle_DEGS = parseInt(player.angle);
var diff = RotTargetAngle_DEGS - playerAngle_DEGS
if (diff < -180) {
diff = diff + 360;
} else if (diff > 180) {
diff = diff - 360;
}

AngleTween.updateTo(‘angle’, playerAngle_DEGS + diff, true);
AngleTween.restart();

Something about the UpdateTo tween is causing it bounce when it hits the 180 / -180 point.
If you ignore the tween and just set the player.angle e.g.

player.angle = playerAngle_DEGS + diff, then it gets past the 180 point, but you lose the smooth rotation.

My heads hurting
Any advice appreciated.

Thanks for the suggestion, but that does not have any acceleration or deceleration on the arrow.

I am now trying to sort it by going back to the original idea of using rotateTo and accelerate the speed property with an easing function

which i got from - Easing Equations

easeInOutQuad (t, b, c, d) {
t /= d/2;
if (t < 1) return c/2tt + b;
t–;
return -c/2 * (t*(t-2) - 1) + b;
};

Where
t = current Time
b = start value
c = Change in value
d = duration

but i am struggling to understand how to call this from the update loop.

Thanks for your useful input.

In update() I would use one of the interpolation methods instead (Linear, SmoothStep).

For your original tween I think it should work if you use a counter as a proxy value; see tween angle from range 0 to 360.

I have finally solved it - I am so happy - literally 3 days of trial and error!
Result is super smooth player rotation.

Tween in Create

AngleTween = this.tweens.add({
targets:player,
angle:0,
ease: ‘Bounce.easeInOut’,
duration: 500
});

In Game Update Loop

var PlayerPosX = player.body.position.x
var PlayerPosY = player.body.position.y
var MousePosX = this.cameras.main.scrollX + game.input.mousePointer.x;
var MousePosY = this.cameras.main.scrollY + game.input.mousePointer.y;
var RotTargetAngle_RADS = (Phaser.Math.Angle.Between(PlayerPosX, PlayerPosY, MousePosX, MousePosY));
var RotTargetAngle_DEGS = parseInt(RadToDeg(RotTargetAngle_RADS));
var playerAngle_DEGS = parseInt(player.angle);
var playerAngle_RADS = degToRad(player.angle);

if (game.input.mousePointer.x > 0) {
var TargetMinusPlayer = RotTargetAngle_DEGS - playerAngle_DEGS
var TargetMinusPlayerAdjusted = TargetMinusPlayer;
if (TargetMinusPlayer < -180) {
TargetMinusPlayerAdjusted += 360;
} else if (TargetMinusPlayer > 180) {
TargetMinusPlayerAdjusted -= 360;
}

var FedInToTween = playerAngle_DEGS + TargetMinusPlayerAdjusted
if (FedInToTween < 0 && Last_FedInToTween > 0 || FedInToTween > 0 && Last_FedInToTween < 0) {
//this is where angle flips from pos to neg or from neg to pos
AngleTween.updateTo(‘angle’, FedInToTween, true);
AngleTween.pause();
} else {
AngleTween.updateTo(‘angle’, FedInToTween, true);
AngleTween.restart();
}
Last_FedInToTween = FedInToTween;
}

@Martin_Turner you can refactor your TargetMinusPlayerAdjusted if statements to this.

var TargetMinusPlayerAdjusted = Phaser.Math.Wrap(TargetMinusPlayer, -180, 180);