You could possibly use Tiled map data. I rolled my own custom solution to this. First, I have JSON with all my line segment data. It looks like this:
var lines = [
{
"x1": 2149,
"y1": 2479,
"x2": 2169,
"y2": 2479,
"type": false
},
{
"x1": 1568,
"y1": 3029,
"x2": 1598,
"y2": 3029,
"type": "fence"
}
]
I created a “type” property so I could set different types of objects to different depths.
Is my code constantly checking if it’s above or below every single depth line? Kind of. What it’s doing is checking to see if the player’s coordinates correspond to an entry in an object every frame.
First of all, I build the line object above with a PHP script. In my YouTube video, I have the tile grid highlighted in green. I have the ability to click on the map in one spot, then click in another and it will alert the coordinates of that line to the screen, then I can click OK to post this line segment to the screen. Here’s an example:
Here’s the code:
linebuilder() {
let clickCount = 0;
let coords = { x1: false, y1: false, x2: false, y2: false };
this.input.on('pointerdown', (pointer) => {
const worldX = Math.round(this.cameras.main.scrollX + pointer.x);
const worldY = Math.round(this.cameras.main.scrollY + pointer.y);
if (clickCount % 2 !== 0) {
coords.x2 = worldX;
coords.y2 = worldY;
const line = prompt('Coordinates', JSON.stringify(coords));
if (line) {
const data = new URLSearchParams(JSON.parse(line));
fetch('tools/linebuilder.php', {
method: 'POST',
body: data
})
.then(response => response.json())
.then(response => {
this.physicsLine(coords);
coords = { x1: false, y1: false, x2: false, y2: false };
});
}
} else {
coords.x1 = worldX;
coords.y1 = worldY;
}
clickCount++;
});
}
Here’s the PHP for that endpoint:
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
$file = '../js/lib/lines.js';
$lines = json_decode(trim(str_replace('var lines = ', '', file_get_contents($file))));
if($lines) {
foreach($_POST as $key => $value) {
$_POST[$key] = (int) $value;
}
$_POST['type'] = false;
$lines[] = $_POST;
foreach($lines as $key => &$value) {
if(gettype($value) == 'object') {
if(!isset($value->type)) {
$value->type = false;
}
}
}
$new = json_encode($lines, JSON_PRETTY_PRINT);
file_put_contents($file, 'var lines = '.$new);
echo $new;
} else {
echo json_encode(['existing lines not found']);
}
This code builds the lines lookup within the scene you’re working with:
physicsLine(line) {
let world = this.scene.get(this.scene.key);
let thisLine = this.line(line.x1, line.y1, line.x2, line.y2).setDepth(3);
thisLine.lineType = line.type;
let x = this.map.worldToTileX(thisLine.x);
let y = this.map.worldToTileY(thisLine.y);
world.physics.add.collider(thisLine, game.player);
world.lines[`${x}_${y}`] = thisLine;
}
physicsLines(lines) {
var world = this.scene.get(this.scene.key);
world.lines = {};
if(typeof lines != 'undefined') {
lines.forEach((line) => {
this.physicsLine(line);
});
}
}
This code sets depth on your layers in update():
spritePosition(sprite) {
var bx = this.map.worldToTileX(sprite.body.x);
var by = this.map.worldToTileY(sprite.body.y);
var x = this.map.worldToTileX(sprite.x);
var y = this.map.worldToTileY(sprite.y);
var pos = sprite.y
var coords = {x:x,y:y};
if(by != y) {
var pos = sprite.body.y;
var coords = {x:bx,y:by};
}
/*
if(bx != x) {
var pos = sprite.body.x;
var coords = {x:bx,y:by};
}
*/
try {
var line = this.lines[`${coords.x}_${coords.y}`];
var vertical = (line.coords.x1 == line.coords.x2);
if(vertical) {
this.structures.setDepth(1.1);
this.fences.setDepth(1.1);
} else {
if(pos > line.y) {
if(line.lineType == 'fence') {
this.fences.setDepth(1.1);
this.structures.setDepth(3);
} else {
this.structures.setDepth(1.1);
this.fences.setDepth(1.1);
}
} else {
this.structures.setDepth(3);
this.fences.setDepth(3);
}
}
} catch(_) {
this.structures.setDepth(3);
this.fences.setDepth(0);
}
}
Pass the player sprite to that method.
I have different layers in my map. I have a static image on the bottom layer, and it never moves. I have a structures layer and a fences layers. Pretty much everything is in the structures layer. You have to watch how you lay things out. With this system, it checks one tile at a time to see where it should position things. This means that if the player overlaps two things at once, and they’re on the same layer, it will cause issues. You’ll have to either create more layers or move things so that does not occur.