Set Isometric image depth with line segment

Hi,

I would like like to manage image depth using line segment as mentionned in this video :

Here’s my codpen to show you : https://codepen.io/sparkkbolo/pen/pogOvLR?editors=0010
the player is in front of the building only at the bottom center of the image but not on the sides.

An idea ? is there an other way to do it ?
Thanks
( soory for my poor english )

Hi, if you want to go for full isometric game I used in the past the lewster plugin for Phaser v2 combined with Tiled editor and was quite good approach and avoids such headaches in most cases. Here it is the port for Phaser v3 which I haven’t tested but maybe is helpful…

Thanks for your reply,
I will try this thanks !

Hello @bolox

I realise this post is 6 years ago, but can I ask if you managed to find a solution/ what is the best solution you found

As I am having this exact same issue right now

Thank you in advance

@AliQassim99 I haven’t done this with isometric graphics, but I’ve done it with orthogonal. Something like this?

@johnSSG Thank you John for your reply, yes this is exaclty what I am looking for, but I am not sure how to implement this in phaser, I can prepare the depth lines and boundries in any software or in Tiled, but then how to use this in phaser? Is your code constantly checking if the character is above or below every single depth line in the map or just if the character is near to the line, etc

Hi there,
It’s Old but In my mind, I load sprites from Tiled for rendering (with depth mostly driven by screen yy), and I also extract objectgroup polygons to build static Matter collision shapes and interaction/trigger areas (bounds/action polygons).
Here a vidéo of my project with tiled :

Here’s my projet finished:

Hope it helps :slight_smile:

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.