Depth and random spawning question

Stamos22

Member
Hello again,

I have a question concerning depth and an issue I can't solve.

I currently have tried two different ways of layering my objects in a top down pseudo 3d game.

The first, is to use depth = - y (some value). This has allowed me to make it possible for my character to go behind objects and create a sense of depth to the world. However, the problem here is that I use a spawner at map creation to throw down a random assortment of vegetation. When it does this, there are always a few trees that have weird depth problems - some of the ones at the top of the screen get drawn over ones that are lower on the screen.

The second method I have tried is Cosmonaut's depth code
Code:
if ds_exists(ds_depth_grid, ds_type_grid) {
    var depthGrid = ds_depth_grid;
    var instNum = instance_number(o_par_depth);
    
    ds_grid_resize(depthGrid, 2, instNum,);
    
    var yy = 0;
    with o_par_depth {
        depthGrid[# 0, yy] = id;
        depthGrid[# 1, yy] = y;
        yy++;
    }
    
    ds_grid_sort(ds_depth_grid, 1, true);
    yy = 0; repeat instNum {
        var instID = ds_depth_grid[# 0, yy];
        with instID {
            event_perform(ev_draw, 0);   
        }
        yy++
    }
    ds_grid_clear(ds_depth_grid, 0);
    
}
This works great for the ranom tree spawning, but there is a problem with my player. I am using a separate object for his weapon (bow). The bow rotates on its origin like a turret and this is critical for the gameplay. The problem is that the bow draw behind the player when I use this code. I believe this is because the origin is above the player's origin? Though I may be wrong as I am a noob. If that's the case, I don't know what to do since the origin needs to be in the centre of the player in order for the bow to rotate properly.

Do any of you clever people have any ideas of how I might sort this out?
 
R

robproctor83

Guest
You may already be doing this, but just to be sure, for depth = -y to work properly the sprite origin has to be fixed at the objects bottom, or more precisely where the feet should touch the ground. As long as everything is on the same z-axis then that should work. If you need some things to be higher up than other (z-axis) you will have to use something like the FC Depth Code like your using now. I have played around a little with his depth system (I love his dialogue system), but not to the extent where I could be of any help to you.

With that said, there are a few ways you could hack a fix into it. You could just do something in that code to check if the object it's iterating over is the bow, and if so reach out and grab the players y and then based on the angle of the bow to the player increase/decrease the y for the bow that is passed to the depthGrid. Something like that would should work.
 

chamaeleon

Member
This works great for the ranom tree spawning, but there is a problem with my player. I am using a separate object for his weapon (bow). The bow rotates on its origin like a turret and this is critical for the gameplay. The problem is that the bow draw behind the player when I use this code. I believe this is because the origin is above the player's origin? Though I may be wrong as I am a noob. If that's the case, I don't know what to do since the origin needs to be in the centre of the player in order for the bow to rotate properly.
I don't have have much to say about the first problem, but for the second, how about every instance having an instance variable that either contains 0 or some specific number that pertains to the particular kind of object (not necessarily GMS object, more like game play object), which serves as an offset for your y, so instead of just storing y in the grid store y+y_offset (or y-y_offset). That way you'd have the origin where you want for rotation, but sort order would be different due to the offset. Or you could not include these objects in the overall draw loop at all, but have them be drawn by the "owner" of it instead (the player instance draw event also draws all accessory sprites), which would ensure proper draw order within the context of that instance.
 
I would do something similar to @chamaeleon.

I would have a parent object for all objects needing depth sorting. I would give the parent object it's own depth value, let's call it simply "z".

At the start of the parent object's step event, use:

Code:
z = y;
Then you use the z variable for depth sorting, but still use the y value for drawing.

All the child objects would call the function event_inherited() at the start of their step event to inherit that code.

For the bow then, after it calls event_inherited() in it's step event, it can then override the z value something like this:

Code:
z = player.y + 1;
That would make the bow's depth be just in front of the player's depth, but it would still retain the correct y value for drawing.

That's my suggestion anyway.
 

Nidoking

Member
If you go with the option of setting the origin of every sprite to be at the bottom, you might also try setting the origin for the bow's sprites to be below the bottom, so that when the bow's y is near than the player's y, it draws in the correct position relative to the player's sprite. Then you adjust the bow's y up or down as necessary when it needs to be in front of or behind the player's sprite.
 
Top