Raycasting with Tilemaps in Phaser

One of the things I was looking to do in my new Phaser game was to get the enemy sprite to move faster when they “saw” our player sprite.

The best way to do this as far as I can see is to cast an imaginary line from one sprite to the other. If this line of sight is broken by an outside object – in our case a tilemap tile – then we treat this as if the enemy cannot see our player sprite. If the line is not broken then we will treat this as if the enemy can see our sprite and we will increase their velocity.

For more on Raycasting Basics go here

Okay, we are going to make some assumptions about where you are with your game:

  • you have a player sprite named “player”
  • you have an enemy sprite named “skeleton”
  • you have a tilemap layer that acts as your foreground platform tiles called “blockLayer”

Firstly, add a couple of variables at the top of your js file:

var ray;
var tileHits = [];

Inside our levels Update function add:

ray = new Phaser.Line(skeleton.x, skeleton.y - 40, player.x, player.y - 40);
var intersect = this.getWallIntersection(ray);

40 being the head height of our sprites.

Create our new function

getWallIntersection: function (ray) {
tileHits = blockLayer.getRayCastTiles(ray, 4, true, false);     //getRayCastTiles(line, stepRate, collides, interestingFace)
    if (tileHits.length > 0) {
        return true;
    }
    return false;
}

We are using the really useful getRayCastTiles function here to check if a ray is hitting a tile.

Back in our Update function:

if (intersect) {
  // A wall is blocking their vision so change them to normal speed
  skeleton.body.velocity.x = enemySpeed;
} else {
    // Enemy can see Player so change them to faster speed
    skeleton.body.velocity.x = enemySpeed * 2;
}

There you go, it’s that easy! Our enemy sprite will now move twice as fast when our player is in their line of sight.