1
\$\begingroup\$

I am trying to figure out the most efficient way to draw sprites in a way that they layer properly based on their Y position.

Lets say I have four objects of the same class named A, B, C, and D, and they all must be drawn. Their respective Y positions are 12, 16, 13, and 17. If I draw A then B then C then D, they will draw and lay over the tops of each other in a weird manner. I want to draw them "largest y is closest." I know you could probably use a sort routine to sort them all based on Y, but I would imagine that would generate a huge amount of lag because of all the calculations, especially when you're needing to draw about fifty or sixty objects.

What's the right way to go about drawing them? How would I modify this to include two different types of objects with similar properties (ie, "creatures" and "projectiles" ?)

\$\endgroup\$
2
\$\begingroup\$

Sort them based on their Y position and draw them. You are over-thinking it. Only worry about the performance if you implement it, it appears slow and you discover (via scientific profiling) that the sorting is the bottleneck.

Fifty or sixty objects is pretty trivial, all things considered. It's very possible you could achieve reasonable performance using a bubble sort that way, depending on what else is going on (and the sorting algorithms supplied to you in the .NET standard library will be more efficient than bubble sort).


There are a few other techniques you can employ, however:

  • If you know the objects, or some subset of the objects, will not move much you can also consider storing them in a list that remains sorted (or a regular list where you just insert new objects into the appropriate positions).

  • If are rendering in 3D space (despite being a 2D game), you can give each sprite a depth (Z) coordinate equivalent to it's layer order, and rely on depth buffering to cause sprites to be drawn correctly. This avoids the CPU-side sorting, but does involve additional work (if you're not already doing it) to treat all the objects as being in 3D space (such as preparing an orthographic projection).

  • Since you're using XNA, if you're using SpriteBatch, there's a Draw overload that takes a layer value. This layer value can be used to order the sprites accordingly.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Oh nice, didn't know about that depth value. It says 0 is default and 1 is back, but could I use any numbers for those with the spritesort (back to front, or front to back?) \$\endgroup\$ – anonymous_asker Feb 13 '15 at 18:09
  • \$\begingroup\$ You can use anything in between and including 0 and 1. The layer depth is basically SpriteBatch implementing my second bullet point for you. The SpriteSortMode flag also allows it to (independently) implement the sorting feature you originally brushed aside as "too slow." They're basically implementations of the available options, so you don't have to manually do it yourself if you don't want. \$\endgroup\$ – user1430 Feb 13 '15 at 18:20
  • \$\begingroup\$ Alright. I'll probably try each of the things you've pointed out, including just doing the sort, and see how each of them work out. Thank you again for your insight, it's been pretty helpful. \$\endgroup\$ – anonymous_asker Feb 13 '15 at 18:27
-1
\$\begingroup\$

I would recomend you to not use this technique, but instead use layers.

In my opinion, layers are the best alternative (of those which I know). Then you would just add each sprite to one of your layers and just loop through each of them with a simple loop, and render the content of each of them.
If that rendering technique doesn't suit you, then you could implement it in any other way, but I strongly recomend you to use layers!

If using layers, you can get rid of the sorting, which will take much performance when the game grows in size. That's why layers was invented, I think.

Good luck!

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.