OK, now I’ve modularized it a bit to keep the logic separated. Give it a whirl and say what you think.
Now there’s a layer.lua with the layer logic and main.lua with program logic.
-- -- layer.lua -- local M = {}; local z; -- z-index display group local MAX\_LAYERS -- max number of layers -- helper functions to keep track of where current z-index is local makeIndex = function(i, order) order = order or "top"; if (i \< MAX\_LAYERS) then -- push indexes up for j = i + 1, MAX\_LAYERS do z.minIndex[j] = z.minIndex[j] + 1; end end local retVal; if (order == "top") then if (i == MAX\_LAYERS) then retVal = z.numChildren + 1; else retVal = z.minIndex[i + 1] - 1; end else -- assume "bottom" retVal = z.minIndex[i] + 1; end return retVal; end M.insertObject = function(object, order) if (not object.zIndex) then print("LAYER: Display object is missing a zIndex property"); return; end z:insert(makeIndex(object.zIndex, order), object) end M.removeObject = function(object, options) options = options or {}; local i = object.zIndex; if (i \< MAX\_LAYERS) then -- pop indexes down for j = i + 1, MAX\_LAYERS do z.minIndex[j] = z.minIndex[j] - 1; end end if (not options.keepObject) then object:removeSelf(); end end M.changeIndex = function(object, newIndex, order) M.removeObject(object, {keepObject=true}); object.zIndex = newIndex; M.insertObject(object, order); end M.init = function(maxLayers) if (not maxLayers) then print("LAYER init(): Must specify number of layers") return; end MAX\_LAYERS = maxLayers; z = display.newGroup(); z.minIndex = {}; for i = 1, MAX\_LAYERS do local r = display.newRect(z, 0, 0, 1, 1); -- z-index placeholder object r.isVisible = false; z.minIndex[i] = i; end return M; end return M;
-- -- main.lua -- local buildInfo = system.getInfo("build"); local buildVersion = tonumber(buildInfo:sub(buildInfo:find("%.")+1)); math.randomseed(os.time()); local random = math.random; local MAX\_LAYERS = 10; -- max # of layers local MAX\_OBJECTS = 100; -- max # of objects local travelTime; -- time to travel across screen local spawnObject; -- predefined function local layer = require("layer").init(MAX\_LAYERS); local onTap = function(event) local object = event.target; local newIndex = object.zIndex \> 1 and object.zIndex - 1 or MAX\_LAYERS; layer.changeIndex(object, newIndex); object.y = object.zIndex \* 20 + 20; return true; end spawnObject = function() local zIndex = random(MAX\_LAYERS); local o = display.newRect(0, 0, 40, 40); local t = display.newText(zIndex, 0, 0, native.systemFont, 10) if (buildVersion \> 2000) then -- Graphics 2.0 o:setFillColor(random(), random(), random()); t:setFillColor(0); else -- Graphics 1.0 o:setFillColor(random(255), random(255), random(255)); t:setTextColor(0); t:setReferencePoint(display.CenterReferencePoint); t.x, t.y = 20, 20; end local g = display.newGroup(); g:insert(o); g:insert(t); g.y = zIndex \* 20 + 20; g.zIndex = zIndex; g:addEventListener("tap", onTap) layer.insertObject(g); g.xScale, g.yScale = 0.01, 0.01; transition.to(g, {time=800, xScale=1.0, yScale=1.0, transition=easing.outElastic}); travelTime = 10000 + random(7000); transition.to(g, {time=travelTime, x=display.contentWidth, onComplete=function(o) transition.to(o, {time=200, alpha=0, xScale=0.01, yScale=0.01, onComplete=function(o) layer.removeObject(o); spawnObject(); -- create new object end}); end}); end -- create MAX\_OBJECTS objects with a random z-index for i = 1, MAX\_OBJECTS do spawnObject(); end
layer.lua exposes these functions:
init(maxLayers)
Must be called to initialize the module. maxLayers is the number of layers wanted
insertObject(object [, “top” | “bottom”])
Inserts a display object into a layer. IMPORTANT : object must have a zIndex property set.
“top” will insert the object above all other objects within the layer.
“bottom” will insert the object under all other objects within the layer.
Defaults to “top” if omitted.
removeObject(object)
Removes an object
changeIndex(object, newIndex [, “top” | “bottom”])
Changes the zIndex of an object
main.lua creates 100 objects (multi-colored square boxes) each with a random zIndex. The boxes move across the screen and when they hit the edge they are removed and a new box is created with a random zIndex. Rinse and Repeat…
New feature: You can tap on any square to send it up to the previous layer.
This is all done without having to redraw the whole stack.