How To Fire Bullets from Facing Direction in Phaser 3

We look at 3 ways to achieve this by converting an angle to a vector

by on 4 minute read


Are you making a shooting game where the main character or spaceship can rotate 360 degrees?

Figuring out how to shoot bullets from any angle a character is facing can be challenging.

The key is being able to convert the rotation angle to a vector. We can do this manually with some trigonometry but Phaser can do this for us!

In this article, we will show you how to do this with Phaser's built-in functions and manually using math functions as a bonus.

First, let's do it the easy way.

Convert Angle to Vector with Arcade Physics

Phaser's Arcade Physics has a velocityFromAngle method that will give you a velocity vector from an angle in degrees. You can also use velocityFromRotation which takes an angle in radians.

GameObjects in Phaser use the angle property for degrees and rotation for radians. Using them interchangeably will anger the Math Gods so don't do it. 😡

Here's a simple example using a rectangle and a circle.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
create()
{
	const x = this.scale.width * 0.5
	const y = this.scale.height * 0.5

	// red rectangle
	const rect = this.add.rectangle(x, y, 100, 50, 0xff0000, 1)

	// vector to edge of rectangle
	const vec = this.physics.velocityFromAngle(rect.angle, 50)

	// draw a circle to show the position
	this.add.circle(x + vec.x, y + vec.y, 10, 0xffffff, 1)
}

We create a red rectangle that is 100 pixels wide by 50 pixels tall. The angle is 0 degrees which means facing right. Phaser uses a right-hand clockwise rotation system.

Then we get a vector from the rectangle's angle with a magnitude of 50 pixels. This means adding the vector to a position will move an object 50 pixels in the direction of the vector.

Since we know the angle is 0 degrees in a right-hand system then we should expect the white circle to be on the right edge of the red rectangle.

Zero Degrees

Change the angle of rect, eg: rect.angle = 45, to test that it works as expected for different angles.

To fire a bullet from this position and in the facing direction just set the x, y as we do for the circle and then set the velocity to vec.

But what if you want the bullet to move faster or slower than 50px per frame?

Here's a variant that gets vec as a direction only. Then we can apply a magnitude to it.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// vector as direction only by setting the speed param to 1
const vec = this.physics.velocityFromAngle(rect.angle, 1)

// manually set a 50px magnitude change in x and y (dx, dy)
const dx = vec.x * 50
const dy = vec.y * 50

// draw a circle like before
this.add.circle(dx, dy, 10, 0xffffff, 1)

// bullet velocity using a magnitude of 300
const vx = vec.x * 300
const vy = vec.y * 300

// set the bullet's velocity with (vx, vy)

The next 2 sections will cover additional options for the geekiest among us.

Convert Angle to Vector Without Arcade Physics

The velocityFromAngle method is just a convenience method. You can use Phaser.Math.Vector2 to achieve the same result.

This would be useful if you are not using Arcade Physics.

1
2
3
4
5
6
7
// create a vector
const vec = new Phaser.Math.Vector2()

// update vector from rotation; not angle
vec.setToPolar(rect.rotation, 50)

// use vec as we did before

The setToPolar method is called by velocityFromAngle so both examples do the same thing. 🤗

This is useful in classes without a reference to the Scene or Arcade Physics.

Convert Angle to Vector with Trigonometry

Lastly, let's look at how we can do what setToPolar does with basic trigonometric functions in case you don't want to use a Phaser.Math.Vector2 instance.

We use cos and sin to convert an angle in radians to an x and y position.

1
2
3
4
const vx = Math.cos(rect.rotation) * 50
const vy = Math.sin(rect.rotation) * 50

// use vx, vy as we did with vec before

The multiplied value of 50 is the magnitude. It can be changed to 1 for just direction like we did above.

Explaining why cos and sin works is out of the scope of this article but remember that cos is adjacent / hypotenuse and sin is opposite / hypotenuse.

Adjacent is along the x-axis and opposite is along the y-axis. See here for more information.

Next Steps

You now know how to convert any angle to a vector that can be used to fire bullets, lasers, or launch angry birds. 🤨

If you haven't already, be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!

Drop your email into the box below.

Don't miss any Phaser 3 game development content

Subscribers get exclusive tips & techniques not found on the blog!

Join our newsletter. It's free. We don't spam. Spamming is for jerks.

Phaser 3 shooter bullets trigonometry

Want tips and techniques more suited for you?


You may also like...


Video Guides


Beginner Guides


Articles Recommended For You

Command Pattern to Undo Player Actions

by on

Are you looking for a clean and reusable way to implement undo for player actions? Perhaps you are making a turn-based …

15 minute read

Advanced Logging with the Strategy Pattern

by on

Have you ever tried debugging a problem with your game that only seems to happen in production? The Developer Tools …

7 minute read

State Pattern for Character Movement in Phaser 3

by on

Writing clean and well-organized code is something all game developers aspire to. We want code to be reusable and easy …

7 minute read

Memory Match in Modern Javascript with Phaser 3 - Part 6

by on

If you've got the basics of Phaser 3 in modern JavaScript down then it might be time to try making something a bit more …

8 minute read

Didn't find what you were looking for?


comments powered by Disqus