# Smooth Player Rotation

**URL:** <https://phaser.discourse.group/t/smooth-player-rotation/8001>\
**Category:** Phaser 3\
**Created:** [November 2, 2020, 10:51am UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001 "2020-11-02T10:51:14Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Martin\_Turner](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/martin_turner/32/4193_2.png) [@Martin\_Turner](https://phaser.discourse.group/u/Martin_Turner)\
**Post date:** [November 2, 2020, 10:51am UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/1 "2020-11-02T10:51:14Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [November 2, 2020, 6:01pm UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/2 "2020-11-02T18:01:46Z")

</div>

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

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

```

What is happening? Wrong rotation or no rotation?

---

<div class="post-metadata">

**Author:** ![Martin\_Turner](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/martin_turner/32/4193_2.png) [@Martin\_Turner](https://phaser.discourse.group/u/Martin_Turner)\
**Post date:** [November 3, 2020, 7:08am UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/3 "2020-11-03T07:08:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [November 3, 2020, 1:55pm UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/4 "2020-11-03T13:55:43Z")

</div>

https://codepen.io/samme/embed/preview/gOpPLLx?height=300&slug-hash=gOpPLLx&default-tabs=js,result&host=https://codepen.io

---

<div class="post-metadata">

**Author:** ![Martin\_Turner](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/martin_turner/32/4193_2.png) [@Martin\_Turner](https://phaser.discourse.group/u/Martin_Turner)\
**Post date:** [November 3, 2020, 2:06pm UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/5 "2020-11-03T14:06:24Z")

</div>

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](http://gizma.com/easing/#l)

> easeInOutQuad (t, b, c, d) {  
> t /= d/2;  
> if (t \< 1) return c/2_t_t + 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.

---

<div class="post-metadata">

**Author:** ![samme](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/samme/32/5275_2.png) [@samme](https://phaser.discourse.group/u/samme)\
**Post date:** [November 3, 2020, 4:15pm UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/6 "2020-11-03T16:15:20Z")

</div>

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](http://labs.phaser.io/view.html?src=src%5Ctweens%5Ctween%20angle%20from%20range%200%20to%20360.js).

---

<div class="post-metadata">

**Author:** ![Martin\_Turner](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/martin_turner/32/4193_2.png) [@Martin\_Turner](https://phaser.discourse.group/u/Martin_Turner)\
**Post date:** [November 4, 2020, 8:14am UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/7 "2020-11-04T08:14:29Z")

</div>

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;  
> }

---

<div class="post-metadata">

**Author:** ![Calabi](https://yyz2.discourse-cdn.com/free1/user_avatar/phaser.discourse.group/calabi/32/3712_2.png) [@Calabi](https://phaser.discourse.group/u/Calabi)\
**Post date:** [November 7, 2020, 4:32pm UTC](https://phaser.discourse.group/t/smooth-player-rotation/8001/8 "2020-11-07T16:32:33Z")

</div>

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

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