Skip list:Drawing Order
Z-ordering in LÖVE is tedious because the engine doesn't offer any support for it. You must draw the sprites in order by yourself, making it hard to handle a large number of sprites on different planes.
With the skip list data structure, you can do:
zlist = makeSkipList(3) -- 3 is the estimated size of the structure. -- It's indicative, but a good guess improves the performance Clown = makeSprite (100, 100, 1, "clown.png") -- x, y, z, image Frogs = makeSprite (100, 110, 1, "frogs.png") -- on the same plane as the Clown, but drawn on top because it's been created after. Tools = makeSprite (90, 120, 0, "tools.png") -- under the clown zlist:insert( Frogs ) zlist:insert( Tools ) zlist:insert( Clown ) -- You can insert them in any order for _, sprite in zlist:iter() do -- draw the sprite in Z order :-) print( sprite.x, sprite.y, sprite.z, sprite.image ) end
Output:
90 120 0 tools.png 100 100 1 clown.png 100 110 1 frogs.png
If you want to change the position of an item on the Z axis, you remove it and insert it back.
Tools.z = 2 zlist:delete(Tools) zlist:insert(Tools) -- now Tools is on top of the pile for _,sprite in zlist:iter() do print(sprite.x, sprite.y, sprite.z, sprite.image) -- draw(sprite) end
Here's the output:
100 100 1 clown.png 100 110 1 frogs.png 90 120 2 tools.png
Toy implementation of makesprite:
do local count = 0 function counter() count = count + 1 return count end end do local lt = function(a,b) if a.z < b.z then return true elseif a.z==b.z and a.id < b.id then return true else return false end end local mt={ __lt=lt, __le=lt } function makeSprite (x,y,z,image) local s={x = x, y = y, z = z, image=image, id = counter()} -- the id field is necessary because, otherwise, items on the same plane would cause troubles. return setmetatable(s,mt) end end