I’ve actually got 2 problems, but one is likely an easier fix than the other…
I have what I was hoping was going to be a script to help make depth sorting easier, which is supposed to update the unit’s depth when in motion, as follows:
var tileWidth = 128;
var tileHeight = 64;
//TILEMAP ARRAY EXAMPLE
levelData =
[[0,0,0,0,0,0],
[0,1,8,8,7,0],
[0,2,9,9,6,0],
[0,2,9,9,6,0],
[0,3,4,4,5,0],
[0,0,0,0,0,0]];
//METRUS GAME OBJECT
class Metrus extends Phaser.Physics.Arcade.Sprite {
constructor(scene, x, y, motion, direction, distance, id, tileX, tileY) {
super(scene, x, y, 'metrustotalsprite', direction.offset, id, tileX, tileY);
this.id = id;
this.name = id;
this.startX = x;
this.startY = y;
this.tileX = tileX;
this.tileY = tileY;
this.distance = distance;
this.direction = direction;
this.motion = motion;
this.speed = 0.1;
const tileHeightHalf = tileHeight / 2;
this.depth = (tileY + tileX) * tileHeightHalf + 65;
this.scene = scene;
unitSprite = this.scene.matter.add.gameObject(this, { shape: 'circle', circleRadius: 15} );
unitSprite.setCollisionCategory(groundunits);
unitSprite.setCollidesWith([ground, groundunits]);
unitSprite.ignoreGravity = true;
unitSprite.displayWidth = 30;
unitSprite.displayHeight = 30;
unitSprite.scale = 0.4;
var circle = new Phaser.Geom.Circle(150, 150, 40);
unitSprite.setInteractive(circle, Phaser.Geom.Circle.Contains);
}
update() {
var tileX = this.tileX;
var tileY = this.tileY;
var newdepth = tileY + tileX * tileHeightHalf + 65;
var olddepth = this.depth;
if (newdepth !== olddepth) {
this.depth = newdepth;
}
var motion = this.motion;
var direction = this.direction;
//console.log('Motion: '+motion+' Direction: '+direction);
//console.log('X:'+tileX+' Y:'+tileY);
if (motion === "walk") {
var walkDirection = this.motion + this.direction;
this.play(walkDirection);
}
if (motion === "attack") {
var attackDirection = this.motion + this.direction;
this.play(attackDirection);
}
if (motion === "idle") {
var idleDirection = this.motion + this.direction;
this.play(idleDirection);
};
}
}
create () {
tileGroup = this.add.group();
dontWalk = this.add.group();
ground = this.matter.world.nextCategory();
groundunits = this.matter.world.nextCategory();
spawnTiles();
//HOW THE UNIT IS GENERATED, (FOR CONTEXT OF THE PROBLEM)
Units[unitId] = this.add.existing(new Metrus(this, centerX + txOffset, centerY + tyOffset, unitAction, unitDirection, 150, unitId, i, j));
//ATTACK BUTTON IS CLICKED
attack.on('pointerdown', function(){
if (attackState == true) {
//ALREADY SELECTED
this.clearTint();
attackState = false
}else{
//NOT YET SELECTED
attackState = true;
this.tint = 0xFF0000;
}
});
//ATTACK TARGET IS CLICKED
this.input.setHitArea(tileGroup.getChildren()).on('gameobjectdown', function(pointer, gameObject, scene) {
if (attackReady == true) {
var attackX = pointer.worldX;
var attackY = pointer.worldY;
var gameTileX = gameObject.x;
var gameTileY = gameObject.y;
gameObject.priorityID=0;
attackSprite.x = attackX;
attackSprite.y = attackY;
attackSprite.alpha = 1;
attackSprite.play('attackanim');
setTimeout(function(){
attackSprite.alpha = 0;
}, 200);
for (var i = 0; i < selectedArray.length; i++)
{
const thisUnit = Units[selectedArray[i]];
thisUnit.targetX = attackX;
thisUnit.targetY = attackY;
var theScene = this.scene;
var speed = thisUnit.speed;
var distance = Phaser.Math.Distance.BetweenPoints(thisUnit, gameObject);
thisUnit.motion = "walk";
theScene.tweens.add({
targets: thisUnit,
x: attackX,
y: attackY,
duration: distance/speed
});
}
attackReady = false;
attackState = false;
}
});
}
update () {
//UPDATE DEPTH SORTING IF MOVING
for (let q in Units) {
if (Units[q].motion == "walk") {
var tileX = Units[q].tileX;
var tileY = Units[q].tileY;
Units[q].update();
}
}
}
spawnTiles () {
//LOOPS THROUGH levelData (LOOPING OMITTED), TILES MADE THIS WAY:
//DEFINE TILE TYPES
//GRASS0
if (tileType==0)
{
thisTile = this.matter.add.sprite(centerX + tx, centerY + ty, 'flatsprite',0, { shape: { type: 'fromVerts', verts: iso, flagInternal: true } }).setStatic(true);
thisTile.depth = centerY + ty;
thisTile.tileX = i;
thisTile.tileY = j;
tileGroup.add(thisTile);
}
//WATER
if (tileType==9)
{
thisTile = this.matter.add.sprite(centerX + tx, centerY + ty, 'flatsprite',5, { shape: { type: 'fromVerts', verts: iso, flagInternal: true } }).setStatic(true);
thisTile.depth = centerY + ty;
thisTile.tileX = i;
thisTile.tileY = j;
dontWalk.add(thisTile);
thisTile.setInteractive();
thisTile.setCollisionCategory(ground);
thisTile.setCollidesWith([groundunits]);
}
}
(I have obviously omitted a fair amount of code for easy readability)
Problem 1: when the unit moves, the update for depth sorting causes the sprite to flicker, as if its being updated constantly but never finishes.
Problem 2: my units don’t collide properly with my collision tiles, they sort of jump through them
I have attached a video to this post to demonstrate, and the live demo is at:
http://astralforge.net
2021-05-23 23-35-22.mkv (3.2 MB)
Thanks!