z-indexing dynamically generated creeps

I’m building a tower defense game where creeps walk through a set path. My problem is that I need creeps closer to the bottom of the screen to be higher in the z-index so that they look on top of the other creeps. Otherwise, the game looks very strange.

Unfortunately the solutions around the forum are to use different display groups to store your objects but in my case it won’t work because they are generated dynamically and their z-index needs to be recalculated in every frame. 

Is there a way around this? How are people dealing with this problem?

Thanks

Using display groups is the accepted method to accomplish this, because you basically “layer” display groups over each other and sort them based on y coordinate (simplified example).

You can still use this solution and check the y coordinate of your creeps and identifying which group they should be inserted in on any given frame. Were you encountering an issue with using the display groups, or have you not gotten to that point yet?

What stumps me is that according to the documentation, once you assign a display object to a display group, the only way to remove it is to remove the group which will in turn remove the display object itself. My creep objects have a lot of info that I cannot lose on each frame.

Could you care to go into a little more detail on your suggestion?

You can just keep adding the creeps to different display groups without removing the display groups, because, ideally, the display groups would stick around until you killed the scene. 

Here’s some of my (very amateur) depth-sorting for Crosstown Smash:

local sT = {} local fAw = 300 -- amount of display groups local fT = display.contentHeight/20 -- absolute topheight of game level local eH = display.contentHeight\*1.5 -- absolute bottomheight of game level sT.gameGroupA = {} local function setupGameGroupA() for a = fAw, 1, -1 do sT.gameGroupA[a] = display.newGroup() sT.gameGroupA[a].name = ("Game Group ".. a) sT.gameGroupA[a].itsname = ("".. a) sT.gameGroupA[a].id = a --print("sT.gameGroupA[a].x = "..sT.gameGroupA[a].x) game7:insert(sT.gameGroupA[a]) end end local function setGroupInan(obj) if obj == nil then return true end if (obj.y) \< fT then sT.gameGroupA[fAw]:insert(obj) end for i=1, fAw do if obj == nil then return true end if (obj.y) \<= (eH+10)-(2\*i) and (obj.y) \> (eH+10)-((2\*i)+2) then if obj == nil then return true end if obj ~= nil then sT.gameGroupA[i]:insert(obj) end end end if (obj.y) \> eH then sT.gameGroupA[1]:insert(obj) end end

Again, this is super-simple, your mileage may vary, blah blah blah, but the main gist is that you are running this in whichever gameloop you’re using, something like this: “sT.setGroupInan(creep[1])”

Let me know if you still need more clarification.

I believe a display object can only be inside one group (or rather, it can only have one parent, but it’s parent group could be inside a group) at a time, so you don’t remove an object from one group to put it in another, you just put it in the other group and it’s automatically removed from the first.

groupA:insert(ufo) groupB:insert(ufo)

After those two lines are executed ufo will only be in groupB.

 Jay

[EDIT] And here’s the part of the docs that say the above: http://docs.coronalabs.com/api/type/GroupObject/insert.html Look in the Gotchas section.

maybe try the concepts in this thread?:  http://forums.coronalabs.com/topic/46610-diffictul-situation-of-ordering-objects-in-a-group/

(tho note that the OP’s question involved an unsortable keyed list, so you could potentially save some trouble if your “native” list of creeps were indexed numerically, then it’s just: sort-on-y (or whatever defines your pseudo-z), and a looped toFront())

hth

Thanks everyone for their help. I didn’t know that assigning the same display object to a different group would actually switch it to the new one. As I learned this, my problem became trivial. I just created a whole bunch of display groups (as many as my screen height) and then 

myDisplaygroup[creep.y]:insert(creep)

Didn’t even need a single calculation for this!

Using display groups is the accepted method to accomplish this, because you basically “layer” display groups over each other and sort them based on y coordinate (simplified example).

You can still use this solution and check the y coordinate of your creeps and identifying which group they should be inserted in on any given frame. Were you encountering an issue with using the display groups, or have you not gotten to that point yet?

What stumps me is that according to the documentation, once you assign a display object to a display group, the only way to remove it is to remove the group which will in turn remove the display object itself. My creep objects have a lot of info that I cannot lose on each frame.

Could you care to go into a little more detail on your suggestion?

You can just keep adding the creeps to different display groups without removing the display groups, because, ideally, the display groups would stick around until you killed the scene. 

Here’s some of my (very amateur) depth-sorting for Crosstown Smash:

local sT = {} local fAw = 300 -- amount of display groups local fT = display.contentHeight/20 -- absolute topheight of game level local eH = display.contentHeight\*1.5 -- absolute bottomheight of game level sT.gameGroupA = {} local function setupGameGroupA() for a = fAw, 1, -1 do sT.gameGroupA[a] = display.newGroup() sT.gameGroupA[a].name = ("Game Group ".. a) sT.gameGroupA[a].itsname = ("".. a) sT.gameGroupA[a].id = a --print("sT.gameGroupA[a].x = "..sT.gameGroupA[a].x) game7:insert(sT.gameGroupA[a]) end end local function setGroupInan(obj) if obj == nil then return true end if (obj.y) \< fT then sT.gameGroupA[fAw]:insert(obj) end for i=1, fAw do if obj == nil then return true end if (obj.y) \<= (eH+10)-(2\*i) and (obj.y) \> (eH+10)-((2\*i)+2) then if obj == nil then return true end if obj ~= nil then sT.gameGroupA[i]:insert(obj) end end end if (obj.y) \> eH then sT.gameGroupA[1]:insert(obj) end end

Again, this is super-simple, your mileage may vary, blah blah blah, but the main gist is that you are running this in whichever gameloop you’re using, something like this: “sT.setGroupInan(creep[1])”

Let me know if you still need more clarification.

I believe a display object can only be inside one group (or rather, it can only have one parent, but it’s parent group could be inside a group) at a time, so you don’t remove an object from one group to put it in another, you just put it in the other group and it’s automatically removed from the first.

groupA:insert(ufo) groupB:insert(ufo)

After those two lines are executed ufo will only be in groupB.

 Jay

[EDIT] And here’s the part of the docs that say the above: http://docs.coronalabs.com/api/type/GroupObject/insert.html Look in the Gotchas section.

maybe try the concepts in this thread?:  http://forums.coronalabs.com/topic/46610-diffictul-situation-of-ordering-objects-in-a-group/

(tho note that the OP’s question involved an unsortable keyed list, so you could potentially save some trouble if your “native” list of creeps were indexed numerically, then it’s just: sort-on-y (or whatever defines your pseudo-z), and a looped toFront())

hth

Thanks everyone for their help. I didn’t know that assigning the same display object to a different group would actually switch it to the new one. As I learned this, my problem became trivial. I just created a whole bunch of display groups (as many as my screen height) and then 

myDisplaygroup[creep.y]:insert(creep)

Didn’t even need a single calculation for this!