Removing multiple objects in order

Hi,

I have a situation where I am firing multiple laser beams from multiple enemies at a random interval.  I am spawning each beam into a table.  I am letting each beam live for about half a second.

I need to remove the beams in the order they were fired, from first to last. I have my beams in a table. 

Do I do a removeself() and nil from the table specifing 1 as the index until the table is empty?

Thanks for any help, Greg

    local spawn1 = spawnbeam({
                    x1= kx,
                    y1 = ky,
                    x2 = player.x,
                    y2=player.y,
                    layer= layer2,
                    color = “red”,
            })

    timer.performWithDelay(600, function()  …have to remove the beams in order here… end, 1)
 

function spawnbeam(params)

        local beam = display.newLine(params.layer,params.x1, params.y1, params.x2,params.y2, params.color )
        if params.color == “red” then
            beam:setStrokeColor( 1,0,0)
        elseif params.color ==“green” then
            beam:setStrokeColor( 0,1,0)
        else
            beam:setStrokeColor( 0,0,1)    
        end    
        beam.strokeWidth = 3
        beam.objTable = beamtable
        beam.index = #beam.objTable +1
        beam.myName=“beam”…beam.index
        beam.objTable[beam1.index]=beam1
    return beam
end  

Last week’s From the Forum has got you covered.

http://forums.coronalabs.com/topic/36698-how-to-remove-a-table-or-array/

Thanks for the info:

Picture this , I am adding objects to a table 3 or four per second at random intervals while at the same time I am trying to remove objects from the start of the table.  Its a bit more complicated…

Greg

I think you’d be better off just spawning the maximum amount of objects you need, then running them through whatever game logic you have, rather than constantly deleting and spawning objects. The first option is a more efficient way to accomplish the same result. Let me know if I should provide more detail.

Consider the suggestion from @Panc Software but to answer your original question you can simulate a queu easily with table.insert and table.remove

table.insert(tab, val) will insert at the end (maxn + 1) while table.remove(tab, 1) will return the value at index 1 remove it from table and decrease the indexes of all the values left in the table. This is fine if you have a small number of values in the table (less than 200). With a larger number of elements in the table it can get slow when it has to decrease the indexes.

Thanks for the info, what it comes down to is I am creating a bunch of beams and torpedoes and I need to let them live for an amount of time, and then kill them off in the order that they were created.  

I have no problem creating a table full of beams and bullets that part works great… when I delete items using the first index of the table, I start getting nil errors after a few deletes, that is where my problem is…

I do such things in an entirely different manner (and avoid this type of timer/closure use like the PLAGUE!), but if I were to offer a suggestion that most closely “fits” your existing code, it would be to insert your objects into the table with a known key (but NOT the table’s numeric index, as you’re currently doing), so that key can be specifically referenced later (and regardless of status of table’s numeric indices). Quick untested example:

local nextUID = 1 function getUID() local currUID = nextUID nextUID = nextUID + 1 return currUID end -- create a beam, assign a unique id, keyed-insert into table local beam = spawnBeam(.... beam.uid = getUID() beamTable[beam.uid] = beam -- create timer with closure around uid for later deletion timer.performWithDelay(600, function() beamTable[beam.uid]:removeSelf() beamTable[beam.uid]=nil end)

Or some-such variation on that approach.

If it were *ME*, I’d have an “age” -type property on my “actors” (your “beams”), check them in an enterFrame loop, and remove them manually there - thus entirely avoiding timers/closures, or needing a uid/key, or relying on numeric table indexes (that are bound to get scrambled eventually (aka “sparse”) with all this timer-based thrashing), etc.

Hi Dave,

Thanks for the key suggestion, I will give it a go.  My ‘torpedoes’ either hit the target or show up after the target has been destroyed.  The hit is easy,  if my target is gone the torpedoes have no collision event to remove them, that is where your ‘aging’ loop would be a great idea.  Do you use a counter or a timestamp comparison in the enterFrame loop for aging?

Greg

My actors have such a counter “built-in” (that is, they get it “for free”) so I naturally have a bias toward that approach. (as disclaimer) But a “birthtime” and delta from current time would be equivalent (so: if birth+600>=current then…), as would a precalculated “deathtime” (so: if current >= death then…)

RE “time”, I’d probably interpret that to mean “ticks” (aka frames) not real time, and imply the /30 or /60 frame rate, so that it matched my counter usage. (same disclaimer) But that’s more to do with your overall handling of time, and really just a preference thing. (if you have a known need to “decouple” framerate from realtime then you probably already know it, or have no idea what i’m talking about :smiley: and so can ignore it and just treat frame_counter/60==one_second)

What I’ve done so far is when my actors get used up, i’m changing their alpha to 0.   I am working on a enterframe garbage collection that will get rid of them when their alpha is zero.  Seems to be valid so far.

Thanks for the hints about decoupling, that is my next issue, I have a timescale that is not related to the real time clock and have to decouple!

Greg

Last week’s From the Forum has got you covered.

http://forums.coronalabs.com/topic/36698-how-to-remove-a-table-or-array/

Thanks for the info:

Picture this , I am adding objects to a table 3 or four per second at random intervals while at the same time I am trying to remove objects from the start of the table.  Its a bit more complicated…

Greg

I think you’d be better off just spawning the maximum amount of objects you need, then running them through whatever game logic you have, rather than constantly deleting and spawning objects. The first option is a more efficient way to accomplish the same result. Let me know if I should provide more detail.

Consider the suggestion from @Panc Software but to answer your original question you can simulate a queu easily with table.insert and table.remove

table.insert(tab, val) will insert at the end (maxn + 1) while table.remove(tab, 1) will return the value at index 1 remove it from table and decrease the indexes of all the values left in the table. This is fine if you have a small number of values in the table (less than 200). With a larger number of elements in the table it can get slow when it has to decrease the indexes.

Thanks for the info, what it comes down to is I am creating a bunch of beams and torpedoes and I need to let them live for an amount of time, and then kill them off in the order that they were created.  

I have no problem creating a table full of beams and bullets that part works great… when I delete items using the first index of the table, I start getting nil errors after a few deletes, that is where my problem is…

I do such things in an entirely different manner (and avoid this type of timer/closure use like the PLAGUE!), but if I were to offer a suggestion that most closely “fits” your existing code, it would be to insert your objects into the table with a known key (but NOT the table’s numeric index, as you’re currently doing), so that key can be specifically referenced later (and regardless of status of table’s numeric indices). Quick untested example:

local nextUID = 1 function getUID() local currUID = nextUID nextUID = nextUID + 1 return currUID end -- create a beam, assign a unique id, keyed-insert into table local beam = spawnBeam(.... beam.uid = getUID() beamTable[beam.uid] = beam -- create timer with closure around uid for later deletion timer.performWithDelay(600, function() beamTable[beam.uid]:removeSelf() beamTable[beam.uid]=nil end)

Or some-such variation on that approach.

If it were *ME*, I’d have an “age” -type property on my “actors” (your “beams”), check them in an enterFrame loop, and remove them manually there - thus entirely avoiding timers/closures, or needing a uid/key, or relying on numeric table indexes (that are bound to get scrambled eventually (aka “sparse”) with all this timer-based thrashing), etc.

Hi Dave,

Thanks for the key suggestion, I will give it a go.  My ‘torpedoes’ either hit the target or show up after the target has been destroyed.  The hit is easy,  if my target is gone the torpedoes have no collision event to remove them, that is where your ‘aging’ loop would be a great idea.  Do you use a counter or a timestamp comparison in the enterFrame loop for aging?

Greg

My actors have such a counter “built-in” (that is, they get it “for free”) so I naturally have a bias toward that approach. (as disclaimer) But a “birthtime” and delta from current time would be equivalent (so: if birth+600>=current then…), as would a precalculated “deathtime” (so: if current >= death then…)

RE “time”, I’d probably interpret that to mean “ticks” (aka frames) not real time, and imply the /30 or /60 frame rate, so that it matched my counter usage. (same disclaimer) But that’s more to do with your overall handling of time, and really just a preference thing. (if you have a known need to “decouple” framerate from realtime then you probably already know it, or have no idea what i’m talking about :smiley: and so can ignore it and just treat frame_counter/60==one_second)

What I’ve done so far is when my actors get used up, i’m changing their alpha to 0.   I am working on a enterframe garbage collection that will get rid of them when their alpha is zero.  Seems to be valid so far.

Thanks for the hints about decoupling, that is my next issue, I have a timescale that is not related to the real time clock and have to decouple!

Greg