Rotating a sprite from one angle to another in phaser

In many phaser ce projects there will come a time where I will want to rotate a sprite from one angle to another. When doing so i will want to have the sprite rotate in a direction that is the shortest angular distance. Thankfully there is a Math Class method in phaser ce that is there for this very purpose called Phaser.Math.rotateToAngle, in this post i will be covering a quick example that makes use of this method.

1 - what to know

This is a post on using a Math class method to rotate a sprite from a starting angle, to a target angle in the fastest direction in phaser ce the javaScript powered game framework. This is not a getting started post on phaser ce, or javaScript in general, so I hope that you have at least some background with phaser before hand.

1.1 - This is a phaser ce 2.x post

In this post I am using phaser community edition 2.11.1 of phaser.

2 - Example of math.rotateToAngle

So for this example I have two sprites one is a ship, and another is a target. I want the ship to rotate to the target, and do so in a way in which it takes the shortest angular distance clockwise or counter clockwise. To do so I make use of Phaser.Math.rotateToAngle.

2.1 - The rotateToTarget method

Here I have the method that will rotate the ship sprite to the target sprite using Math.rotateToAngle. In addition when it reaches the target it also sets a new target as well.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var rotateToTarget = function (game) {
var data = game.data,
ship = data.ship,
target = data.target;
ship.rotation = Phaser.Math.rotateToAngle(ship.rotation, ship.data.targetRadian, 0.05);
if (ship.rotation === ship.data.targetRadian) {
ship.data.targetRadian = Math.PI * 2 * Math.random();
positionTarget(target, ship);
}
};

2.2 - The Position target helper

This helper just sets the position of target sprite to the current target angle that is stores in the ships data object.

1
2
3
4
var positionTarget = function (target, ship) {
target.x = game.world.centerX + Math.cos(ship.data.targetRadian) * 100;
target.y = game.world.centerY + Math.sin(ship.data.targetRadian) * 100;
};

2.3 - Make the sprites

A simple helper that makes the sprites.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var mkSprites = function (game) {
var data = game.data;
// ship
var ship = data.ship = game.add.sprite(game.world.centerX, game.world.centerY, 'sheet', 1);
ship.data.targetRadian = Math.PI;
ship.anchor.set(0.5, 0.5);
// target
var target = data.target = game.add.sprite(0, 0, 'sheet', 0);
target.anchor.set(0.5, 0.5);
positionTarget(target, ship);
};

2.4 - make the Sheet

A simple canvas solution for making a sprite sheet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// make a sprite sheet
var mkSheet = function (game) {
// sprite sheet generated by canvas
var canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
canvas.width = 96;
canvas.height = 32;
// target
ctx.fillStyle = '#ff0000';
ctx.fillRect(0, 0, 31, 31);
// triangle
ctx.beginPath();
ctx.moveTo(34, 8);
ctx.lineTo(62, 16);
ctx.lineTo(34, 24);
ctx.closePath();
ctx.fill();
game.cache.addSpriteSheet('sheet', null, canvas, 32, 32, 2, 0, 0);
};

2.5 - Tie it all together with Phaser.game

Now to get everything to work by creating an instance of Phaser.Game, calling the mkShett, and mkSprite helpers in the create method of a state object. In addition I call my roatteTotarget method on each frame tick in the update method of the state, and of course I start the state.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
var game = new Phaser.Game(320, 240, Phaser.AUTO, 'gamearea');
game.state.add('demo', {
create: function () {
game.data = game.data || {};
mkSheet(game);
mkSprites(game);
},
update: function () {
rotateToTarget(game);
}
});
game.state.start('demo')

This results in the ship rotating to the target, at which point a new target is created, and the process repeats as expected.

3 - Conclusion

So this is just one of many such methods in phaser that help with common tasks such as this resulting in me spending less time creating and finding solutions for problems, and spending more time focusing on what sets my project apart from others. If you would like to see more examples of this, or have any questions or concerns be sure to let me know in the comments, and that you for reading.