# Pathfinding

Pathifnding is not built into Phaser, thus we must use external resources. In this example we will be using the A* search algorithm from https://github.com/bgrins/javascript-astar.

A beginners guide and to A* search algorithm and game developer tips can be found here.

First, we create a tilemap and place a ball object on it (tilemap tutorial)  like this: Also you need to enable physics for the ball.

Then, in the source editor, we first need to include the A* algorithm. Head to the source editor and create a new file, call it ‘astar.js’, copy-paste the contents from the original A* source here and then drag the file to the ‘lib’ folder: Then we include this script in the ‘index.html’ file: The code:

```"use strict";
window.Pathfinding.state.menu = {
create: function() {
//create objects
this.tiles = mt.create("tiles");
this.ball = mt.create("ball");

var wallTiles = 2; //index of tiles which are considered as walls
this.tileWidth = this.tiles.map.tileWidth; //tilemap grid cell width
this.tileHeight = this.tiles.map.tileHeight; //tilemap grid cell height
this.x = 0; //x coordinates for moving the ball
this.y = 0; //y coordinates for moving the ball
this.temp; //variable for storing the next tile to move towards
this.drawList;
this.isMoving = false;

//converts Phaser tilemap data into a 2D array usable by the A* algorithm, e.g.
//[1,1,1,1,1]
//[1,1,0,1,1]
//[1,1,0,1,1]
//[1,1,0,1,1]
//[1,1,1,1,1]
//where 0=wall and 1=walkable node
var data = this.tiles.map.layer.data;
var rawGrid = [];
for (var i = 0; i < data.length; i++) {
rawGrid[i] = [];
for (var j = 0; j < data[i].length; j++) {
if (data[i][j].index === wallTiles) rawGrid[i][j] = 0;
else rawGrid[i][j] = 1;
}
}

this.graph = new Graph(rawGrid); //creates a graph for the a* algorithm

//on mouse click moves the ball to the clicked tile
this.input.onDown.add(function() {
if (this.isMoving) {
this.stopPath(this.ball);
this.erasePath();
}
this.getPath(this.ball, this.input.activePointer);
}, this);
},

update: function() {
//if movement flag is true, the ball continues to move
if (this.isMoving) {
this.traversePath(this.ball);
}
},

//calculates shortest available path and gives the result as an array of tile coordinates
getPath: function(sprite, mouse) {
var start = this.graph.grid[Math.floor(sprite.y / this.tileHeight)][Math.floor(sprite.x / this.tileWidth)];
var end = this.graph.grid[Math.floor(mouse.y / this.tileHeight)][Math.floor(mouse.x / this.tileWidth)];
this.result = astar.search(this.graph, start, end);
this.drawPath();
this.isMoving = true;
},

traversePath: function(sprite) {
//if this is the first time calling this function for the current path or one tile has already been traversed,
//gets the coordinates of the next tile with result.shift() as in a FIFO structure
//if the result array has been emptied, stops the pathwalking
if (!this.temp || this.game.physics.arcade.distanceToXY(sprite, this.x, this.y) <= 4) {
if (!this.result.length) {
this.stopPath(sprite);
this.erasePath();
return;
} else {
this.temp = this.result.shift();

//calculates the x and y coordinates towards which to move the ball
this.x = this.temp.y * this.tileWidth + this.tileWidth / 2;
this.y = this.temp.x * this.tileHeight + this.tileHeight / 2;
}
}
//moves the ball
//the ball DOES NOT stop moving once it has reached its goal, hence the distanceToXY()<=4 above
//moveToXY(object to move, where to move X, where to move Y, speed);
this.game.physics.arcade.moveToXY(sprite, this.x, this.y, 300);
},

//empties the temp variable and flags movement as false, thus preventing the execution of other functions
stopPath: function(sprite) {
this.isMoving = false;
this.temp = null;
sprite.body.velocity.x = 0;
sprite.body.velocity.y = 0;
},

//draws the path by creating sprites within an array (for more convenient destroying
drawPath: function() {
this.drawList = [];
for (var i = 0, l = this.result.length - 1; i <= l; i++) {
if (i < l) this.drawList.push(this.game.add.sprite(this.result[i].y * this.tileHeight, this.result[i].x * this.tileWidth, '/pathPoint.png'));
else this.drawList.push(this.game.add.sprite(this.result[i].y * this.tileHeight, this.result[i].x * this.tileWidth, '/pathFinish.png'));

}
this.ball.bringToTop();
},

//destroys path visuals
erasePath: function() {
for (var i = 0; i < this.drawList.length; i++) {
this.drawList[i].destroy();
}
this.list = null;
}
};
```

Click on non-wall tiles to move the ball around:

Full sample available here.

## 4 comments on “Pathfinding”

1. robin says:

How do I get the full sample, I clicked the link and registered but can’t find the code?

2. Marco says:

Can any update this to Phaser 3?
Thanks for Reply

3. Jeniffer Littlewood says:

I liked the report and assume you’ve got more such material?
If yes, so please note it as it’s somewhat uncommon for me at the current instant,
and not just for me personally, that is my opinion.

4. Rebekah Kearney says:

I see the author has floor knowledge it the topic as well as some
practical expertise. Such type of info is more precious than copypasted blog posts thoughts.