Are you are making a roguelike or dungeon crawler?
Do you want the player to only see what is visible based on where they are standing?
Where enemies or items behind a wall, in the next room, or around the corner should be hidden until the player has line of sight?
Then what you need is a proper field of view algorithm.
Another alternative is this simpler fog of war effect if you don't need a proper field of view..
In this article, we will go over using the MRPAS algorithm to implement a field of view effect in Phaser 3 with tilemaps.
MRPAS
MRPAS is a restrictive field of view algorithm that stands for Mingo's Restrictive Precise Angle Shadowcasting.
This algorithm generally produces a visually appealing and more natural-looking field of view than other algorithms and is popular amongst roguelikes.
It is probably used in a roguelike you recently played!
In this example, we will be using the mrpas NPM package.
You can install it in your project using this command:
npm install mrpas
Setting Up Mrpas in a Scene
Our example will be in TypeScript. You can ignore all the types if you are using modern JavaScript.
If you are using legacy JavaScript then… what are you waiting for? 🤔
We have a free book to help you get started with modern JavaScript in Phaser 3 so there's no excuse. Get the book and upgrade yourself!
Learn to make an Infinite Jumper in Phaser 3 with modern JavaScript!
Drop your email into the box below to get this free 60+ page book and join our newsletter.
Note that we are going to skip over the tilemap set up code and focus on using the mrpas
library.
Here's what the Scene looks like:
|
|
We are importing the mrpas
library on line 3.
Then on lines 23 - 26 we create an Mrpas
instance and store it in the fov
class property.
The Mrpas
constructor takes width, height, and a function used to determine if a tile can be seen through. The opposite of things like a wall or door–unless you are Superman.
We set it to the inverse of tile.collides
which means anything that cannot collide with the player can be seen through.
For example, a floor tile will not block vision. A wall tile will block vision.
Using the Field of View
Getting the field of view effect to work takes just 3 steps:
1. Hide all the tiles.
2. Use MRPAS to calculate the tiles within the field of view.
3. Only make those tiles visible.
To start, add this method to your Scene:
|
|
Notice that we are only turning off tiles that the camera can see. Anything outside of the current camera view is ignored.
To hide the tile we simply set alpha
to 0
on line 33.
Add a call to this.computePOV()
in the Scene's update()
method and your tiles should no longer be visible.
Next, let's calculate FOV and turn on the visible tiles.
|
|
We get the current position of the player and then use it as the origin in our call to this.fov.compute()
on line 10.
The number 7
on line 13 is the radius. Make this bigger or smaller to adjust the field of view size. You can also use Infinity
.
The next two arguments are where the magic happens.
First, is a function that should return whether a tile is currently visible or not. That is determined by alpha
greater than 0
.
Next, is a function that sets a tile to be visible. We do that by setting the alpha
to 1
.
Try this out and tiles within the field of view will appear while others will disappear.
Simple Improvements
We can make this effect a little nicer by tinting invisible tiles a dark color and fading out tiles furthest from the player.
Only 3 changes are needed:
|
|
First, instead of setting alpha = 0
when we loop through the visible tiles, we set alpha = 1
and add a tint
of 0x404040
on lines 12 and 13.
Then we change our check for whether a tile is visible or not from tile.alpha > 0
to tile.tint === 0xffffff
. This means a tile with no tint or a white tint is assumed to be visible.
Lastly, we adjust alpha
based on the distance from the player for tiles that are in the field of view on lines 38 - 42.
You should get something that looks like this:
Next Steps
We used a single tile layer to keep the example code simple. You will have to handle any other layers that you might have.
There are more things you can add like fading the tiles as they go in and out of visibility.
An alternative to tinting tiles is to add another layer with only black tiles that you fade in and out. This can also be used to keep unexplored sections hidden.
A great example of these features is Dungeon Dash.
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.