Hi there!
I’m toying with some code from a pathfinding tutorial, this one here, it’s really neat.
I’m trying to set the zoom on the camera. When the zoom is not applied, the path finding works fine. And it follows the player. But with the zoom on, using setZoom(2, 2), the pathfinding algorithm breaks. As in the code, the easystar library recieves a grid and and gives you a path if I’m not mistaken. Heres the code I’m working with.
import Phaser from 'phaser'
import EasyStar from 'easystarjs'
let MyScene = new Phaser.Class({
Extends: Phaser.Scene,
initialize:
function MyScene (config)
{
Phaser.Scene.call(this, { key: "MyScene" });
this.checkCollision = this.checkCollision.bind(this)
this.getTileID = this.getTileID.bind(this)
this.handleClick = this.handleClick.bind(this)
this.moveCharacter = this.moveCharacter.bind(this)
},
init: function () {},
preload: function () {
this.load.image('tileset', 'assets/gridtiles.png')
this.load.tilemapTiledJSON('map', 'assets/map.json')
this.load.image('phaserguy', 'assets/phaserguy.png');
},
create: function () {
this.input.on('pointerup',this.handleClick);
this.camera = this.cameras.main;
this.camera.setBounds(0, 0, 20*32, 20*32)
let phaserGuy = this.add.image(32, 32, 'phaserguy')
phaserGuy.setDepth(1)
phaserGuy.setOrigin(0, 0.5)
this.camera.startFollow(phaserGuy)
this.camera.setZoom(2, 2)
this.player = phaserGuy
this.map = this.make.tilemap({key: 'map'})
let tiles = this.map.addTilesetImage('tiles', 'tileset')
this.map.createLayer(0, tiles, 0, 0)
this.marker = this.add.graphics()
this.marker.lineStyle(3, 0xffffff, 1)
this.marker.strokeRect(0, 0, this.map.tileWidth, this.map.tileHeight)
this.finder = new EasyStar.js()
// We create the 2D array representing all the tiles of our map
let grid = [];
for(let y = 0; y < this.map.height; y++){
let col = [];
for(let x = 0; x < this.map.width; x++){
// In each cell we store the ID of the tile, which corresponds
// to its index in the tileset of the map ("ID" field in Tiled)
col.push(this.getTileID(x,y));
}
grid.push(col);
}
this.finder.setGrid(grid);
let tileset = this.map.tilesets[0]
let properties = tileset.tileProperties
let acceptableTiles = []
// We need to list all the tile IDs that can be walked on. Let's iterate over all of them
// and see what properties have been entered in Tiled.
for(let i = tileset.firstgid-1; i < tiles.total; i++){ // firstgid and total are fields from Tiled that indicate the range of IDs that the tiles can take in that tileset
if(!properties.hasOwnProperty(i)) {
// If there is no property indicated at all, it means it's a walkable tile
acceptableTiles.push(i+1);
continue;
}
if(!properties[i].collide) acceptableTiles.push(i+1);
if(properties[i].cost) this.finder.setTileCost(i+1, properties[i].cost); // If there is a cost attached to the tile, let's register it
}
this.finder.setAcceptableTiles(acceptableTiles)
},
update: function (time, delta) {
let worldPoint = this.input.activePointer.positionToCamera(this.cameras.main)
// Rounds down to nearest tile
let pointerTileX = this.map.worldToTileX(worldPoint.x);
let pointerTileY = this.map.worldToTileY(worldPoint.y);
this.marker.x = this.map.tileToWorldX(pointerTileX);
this.marker.y = this.map.tileToWorldY(pointerTileY);
this.marker.setVisible(!this.checkCollision(pointerTileX,pointerTileY));
},
checkCollision: function (x, y) {
let tile = this.map.getTileAt(x, y)
return tile.properties.collide == true
},
getTileID: function(x, y) {
let tile = this.map.getTileAt(x, y)
return tile.index
},
handleClick: function (pointer) {
console.log("pressed tile")
let x = this.camera.scrollX + pointer.x;
let y = this.camera.scrollY + pointer.y;
let toX = Math.floor(x/32);
let toY = Math.floor(y/32);
let fromX = Math.floor(this.player.x/32);
let fromY = Math.floor(this.player.y/32);
console.log('going from ('+fromX+','+fromY+') to ('+toX+','+toY+')');
let scene = this
this.finder.findPath(fromX, fromY, toX, toY, function( path ) {
if (path === null) {
console.warn("Path was not found.");
} else {
console.log(path);
scene.moveCharacter(path)
}
});
this.finder.calculate(); // don't forget, otherwise nothing happens
},
moveCharacter: function (path) {
let scene= this
let tweens = []
for (let i = 0; i < path.length-1; i++) {
let ex = path[i+1].x
let ey = path[i+1].y
tweens.push({
targets: this.player,
x: {value: ex*this.map.tileWidth, duration: 200},
y: {value: ey*this.map.tileHeight, duration: 200}
})
}
scene.tweens.timeline({
tweens: tweens
})
},
The code is basically the same from the example.
For some reason, when I zoom using the camera, the grid becomes broken. I would guess that its a scaling issue but I’m unsure?
If anyone knows anything about pathfinding algorithms and/or libraries, please let me know. I’d really appreciate it, thanks.