I am in the process of writing a 2D game engine, and a dilemma emerged. Let me explain the situation...
I have a Scene class, to which various objects can be added (Drawable, ParticleEmitter, Light2D, etc), and as this is a 2D scene, things will obviously be drawn over each other.
My first thought was that I could have basic add and remove methods, but I soon realized that then there would be no way for the programmer to control the order in which things were drawn.
So I can up with two options, each with its pros and cons.
A) Would be to split the scene in layers. By that I mean instead of having the scene be a container of objects, have it be a container of layers, which are in turn the containers of objects.
B) Would require to have some kind of z-coordinate, and then have the scene sorted so objects with lower z get drawn first.
Option A is pretty solid, but the problem is with the lights. In what layer do I add it? Does it work cross-layer? On all bottom layers? And I still need the Z coordinate to calculate the shadow!
Option B would require me to change all my code from having Vector2D positions, to some kind of class that inherits from Vector2D and adds a z coordinate to it (I don't want it to be a Vector3D because I still need all the same methods the 2D kind has, just with .z clamped on).
Am I missing something? Is there an alternative to these methods?
Edit: it was hard to decide with which option should I go, but I chose option B, adding the z coordinate. Some other design choices that might help others reading this question:
The actual map is a 2D space, and therefor, all positions should be Vector2D instances. But, as I also need a third coordinate, I made a new class, called ScenePosition, which inherits from Vector2D and just adds a z option. What was crucial was to keep the methods thinking that they are still operating on a Vector2D instance.
There is no way that sorting the scene by the z axis on every frame would be efficient, so watch out when adding things to the scene. For example: you would add a
4at the end of this list, not the beginning:
[1, 2, 3].
I chose to have a
changedOrderproperty on the Scene, which you set to true when you change the z coordinate of some object. Then, the array is sorted before rendering, and
changedOrderis set to