Hi. I’m trying to draw the game world (the view is Zelda type, Stardewvalley, Enter the gungeon), but I just can not find a way to sort the objects.
I have a bidemensional array of list of objects that are in each grid. What I do is go through the array and separate the objects that are in each cell by layers and I draw each layer according to its priority. Objects have a priority property within the row they are in (so they do not always overlap in the same order), so some layers have more than one list (according to their prority of overlap). This way it works well, but when I get to objects like a butterfly, bird or an arrow (something flying), I have no idea how to handle the depth in which they are drawn, whether they are drawn in front of or behind large objects such as trees or houses, because the layer of flying objects is the last one that is drawn and they are always ahead.
If anyone can give me some idea of how the games do the order…
Thanks in advance.
I’m no expert, and haven’t even done anything like this personally, but if I was trying to tackle this I would draw the grid going from top to bottom, left to right. So at location 1,1, draw everything in that location based on a layer number, with arrows, birds etc having a high layer number so they are drawn last, then move onto the next grid and repeat.
As for locations / images, rather than the arrow image being 5 pixels high and 30 pixels wide - to simulate it flying across the screen, I would make the image something like 100 pixels high and 30 wide, and draw it at the grid location minus the height - that way it will draw over the grids above.
Hopefully this will give you an idea, but I’m sure some of the more experienced game developers here will give you better tips. I’m interesting to know if I’m on the right path with the above too.
SpriteBatch.Draw calls have a depth parameter that you can let it sort objects by, by specifying SpriteSortMode.BackToFront or FrontToBack in the SpriteBatch.Begin call.
This only works if you can batch all your objects in one run however, because the objects are sorted at the end of the batch and then drawn as usual in that order. If you have multiple batches, instead you’ll want to pass DepthStencilState.Default to your SpriteBatch.Begin so the depth buffer is used to check if rendered objects are actually in front of others. This works in combination with the depth parameter in the SpriteBatch.Draw calls, just like the previous technique. This doesn’t play nice with transparent sprites though, so you’ll want to draw those last if you use the depth buffer. You can write a custom shader that clips pixels with zero alpha and pass it to SpriteBatch.Begin to bypass this issue if you need it. That doesn’t solve the issue for partial transparency though, but for now I’ll assume that isn’t necessary
If you need some help implementing any of this, feel free to ask
Thanks, but my problem is more algorithmic than technical. I know the existence of the depth parameter. What I want to know is the algorithm (theoretically, not necessarily in code) of giving depth values to objects in types of games like StardewValley.
X <-- Sprite position X-Axis
Y <-- Sprite postion Y-Axis
Z <-- Feet position Y-Axis in 2D
Sort your entities by Feet postion before rendering this just what I did.
Thanks, I made a small combination to calculate the depth according to the position, more or less the previous message but also verifying the X-coordinate, in case one overlaps.
cons_depth_y = 1f / WorldHandler.MapSize.Y;
cons_depth_x = 0.00001f / WorldHandler.MapSize.X;
depth = (position.Y + Dimention.Y) * cons_depth_y + position.X * cons_depth_x;