depth sorting

Hi all

I am having some trouble ordering sprites within a display group.
I want to order them so the enemy’s closer to the bottom of the screen are rendered last.

line 27 prints out the order correctly i.e.

1 1 - 0
2 2 - 20
3 3 - 40
4 5 - 80
5 4 - 140

but if I uncomment line 28 --enemyHolder[k]:toFront()

I get outputs like this

1 4 - 0
2 5 - 20
3 2 - 40
4 1 - 80
5 3 - 140

I am new to lua and corona so I’m not sure if I am going about this in the correct way.

any help with this would be very much appreciated

thanks

Mac

here is a code example

[lua]display.setStatusBar(display.HiddenStatusBar)

local enemyArray = {}

local enemyHolder = display.newGroup();

function sortDepth()

local depthList = {}

for i = 1,enemyHolder.numChildren do
depthList[i] = enemyHolder[i].y
end

list = {}

for name,value in pairs(depthList) do
list[#list+1] = name
end

function byval(a,b)
return depthList[a] < depthList[b]
end
table.sort(list,byval)

for k=1,#list do
print (k…" "…list[k] … " - " … depthList[list[k]])
–enemyHolder[k]:toFront()
end
print(’ ')

end

function touched(event)

local t = event.target

local dp = function()

sortDepth()

end

if event.phase == “ended” and t.hit == false then

transition.to(t, {time = 200, y = t.y+20, onComplete = dp})

end

end

function createEnemy()

local _touched = function(event)
touched(event)
end

local _n = display.newGroup()

local img = display.newImage(“enemy.png”)

_n.hit = false;
_n.speed = math.random(300,500);
_n.x = (enemyHolder.numChildren * 20)
_n.y = (enemyHolder.numChildren * 20)
_n:insert(img)
_n:addEventListener( “touch”, _touched )

enemyHolder:insert(_n);

end

for i=1,5 do createEnemy() end[/lua] [import]uid: 12378 topic_id: 5304 reply_id: 305304[/import]

Hi there,

Here’s some working code, I’ve cleaned up stuff that I don’t think is necessary, but feel free to add back in:

[lua]display.setStatusBar(display.HiddenStatusBar)

local enemyArray = {}
local enemyHolder = display.newGroup()

function sortDepth()

function byval(a,b)
return a.y < b.y
end

table.sort(enemyArray,byval)

for k=1,#enemyArray do
enemyArray[k]:toFront()
end
print(’ ')

end

local function touched(event)
local t = event.target
local dp = function()
sortDepth()

end

if event.phase == “ended” and t.hit == false then

transition.to(t, {time = 200, y = t.y+20, onComplete = dp})

end

end

function createEnemy()

local img = display.newImage(“enemy.png”)

img.hit = false;
img.speed = math.random(300,500);
img.x = (enemyHolder.numChildren * 20)
img.y = (enemyHolder.numChildren * 20)
img:addEventListener( “touch”, touched )
enemyHolder:insert(img);
enemyArray[#enemyArray + 1] = img

end

for i=1,5 do createEnemy() end[/lua]

Here’s the basic approach:

  1. I’m using your enemyArray table to store references to each of the enemies you create (also note that I removed the extra display groups you were creating - _n - since I don’t see why they’re needed. Although this may be for something you plan to implement, in which case feel free to add it back in. :slight_smile:

  2. I’ve modified the sort function to sort the enemyArray based on the y value of the enemies

  3. Last step is to iterate through the array and bring them to the front in the order they appear in the array

  4. I also removed the extra _touched function, since you can just use your plan old touched function in your event listener call - again, perhaps there’s a reason for doing it the way you did, but it was helpful for me to remove that to simplify what I was looking at.

  5. As I look at this, it could probably be simplified even further by using sortDepth as your onComplete callback function, if that’s all you need to do after an object moves.

Hope that helps. Let me know if anything is unclear.

Darren [import]uid: 1294 topic_id: 5304 reply_id: 17825[/import]

Thanks for this thread, I’m sure to find it useful later. Am I to understand correctly then that we have (as of yet) no way to order elements other than the order we add them to the screen?

I’m fine with that, just want to be clear :slight_smile:

It’s all really good to know. [import]uid: 14327 topic_id: 5304 reply_id: 17834[/import]

Corona provides :toFront() and :toBack() methods for display objects, but to my knowledge there is no way currently to insert a display object at an arbitrary level (like addChildAt() in ActionScript 3) and have all of the other display objects move up a level to accommodate that one. [import]uid: 1294 topic_id: 5304 reply_id: 17836[/import]

Hi Darren

Thanks very much for your help, your example code is exactly what I was trying to achieve.

looks like I was over complicating things a bit.

thanks again

Mac [import]uid: 12378 topic_id: 5304 reply_id: 17854[/import]