2D Isometric depth sorting entities (only) formula not working

65 views Asked by At

Screenshot of the current state of my engine (C#/MonoGame)

i => (int) (Math.Floor((((x + grid.view.camera.x - grid.view.viewport.x) - tile_width_half) / tile_width_half + (y + grid.view.camera.y - grid.view.viewport.y) / tile_height_half) / 2));
        
j => (int)(Math.Floor(((y + grid.view.camera.y - grid.view.viewport.y) / tile_height_half - (((x + grid.view.camera.x - grid.view.viewport.x) - tile_width_half) / tile_width_half)) / 2));

public static int i(Grid grid, int layer, float x, float y)
        { return i(grid, x, y + (layer * ((grid.info.tile.width * grid.view.viewport.scale) / 2))); }
//use the i above
        
public static int j(Grid grid, int layer, float x, float y)
    { return j(grid, x, y + (layer * ((grid.info.tile.height * grid.view.viewport.scale) / 4))); }
//same

Here are my formulas to get I and J of an entity (the floor is layer 0).

public static float distance_entity(Grid grid, Entity entity, int L, int I, int J, int depth = 1000)
{
    sorti = i(grid, L, I, J);
    sortj = j(grid, L, I, J);

    sortx = x(grid, sorti, sortj);
    sorty = y(grid, sorti, sortj);

    return (float) (sortx + sorty + 0.001 * depth);
}

Here is how I get the distance. Unfortunatly it only works for some of the entity (trees on the screenshot) and when I switch scenes, the order seems to be slightly different and less working. Tho if I switch several times it gets the current order you see on the first screenshot. There are more mistakes than what it is shown.

enter image description here

I dont know if the scene bug is related to the distance not being calculated correctly. Will see. (I just put the entity as a parameter in case I would need it) The issue is that my tree is only one tile. The rest are just image blit on top.

Is it even possible to have the right distance like that ?

Weirdly enough, the tile that are usually badly sorted are the base one in my tile array.

this how I draw an entity :

X = entity.data.x;
Y = entity.data.y;

for (int j = 0; j < entity.data.height; j++)
{
    for (int i = 0; i < entity.data.width; i++)
    {
        I2 = Isometry.i(this, X + view.viewport.x - view.camera.x + (i * (info.tile.width * view.viewport.scale)), Y + view.viewport.y - view.camera.y + (j * (info.tile.height * view.viewport.scale))) - 3;
        J2 = Isometry.j(this, X + view.viewport.x - view.camera.x + (i * (info.tile.width * view.viewport.scale)), Y + view.viewport.y - view.camera.y + (j * (info.tile.height * view.viewport.scale))) - 2;

        X2 = Isometry.x(this, I2, J2);
        Y2 = Isometry.y(this, I2, J2);
        
        if (view.viewport.is_visible(X2, Y2))
            Assets.blit(entity.info.asset,X2 + view.viewport.x - view.camera.x, Y2 + view.viewport.y - view.camera.y, entity.data.start_tile_i + i, entity.data.start_tile_j + j, info.tile.width, info.tile.height, view.viewport.scale);
    }
}

Note that X and Y, comes

I tried adding the entity's real height but didnt do any wonders..

On internet, not a lot on isometric depth sorting with regular tiles and not cubes. I got that formula from a website using cubes as well.

Also English is not my mother tongue, it is possible sometimes I just do not type the right worlds to get results and my country's dev scene is a bit dead. Not much info.

Also : The viewport and camera are not the ones included in MonoGame but are my own set of classes.

1

There are 1 answers

0
Milsan On BEST ANSWER

The problem was that I only sorted taking in account the trunk and not the entire width. It now works very well. I let this post like this, I think I can be really usefull as I wasnt able to find a lot on the subject on internet.

public static int distance(Entity entity)
{
    sortx = x(entity.position.I, entity.position.J);
    sorty = y(entity.position.I, entity.position.J);

    return (int) (sortx + sorty * entity.width() + entity.position.depth);
}

(depth of 500 for trees)