How do you manipulate spawned objects?

I’ve got a spawn function that randomly spawns squares that move from off-screen left to off-screen right. At a certain point, I want all the spawned squares (there are usually at least 30 on-screen at any given point) to simultaneously move downwards off-screen. However, I don’t know how to issue a command to all spawned objects.

My spawn function is very simple, and looks like this:

local function squareSpawn (event) local square = display.newRect(50, 50, 25,25) square.x = -100 square.y = math.random(0,1024) transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square :removeSelf() end})endtimer.performWithDelay(math.random(20,35),squareSpawn,0)[/code]When a certain conditional statement is met, I want some command like this to kick in:transition.to(all squares, {time = 1000, delay = 0, y = all squares.y + 920})[/code]I'm thinking the key might be in the method described here: http://blog.anscamobile.com/2011/09/how-to-spawn-objects-%E2%80%94-the-right-way/, but, being a beginner, I'm not sure how to apply what is being taught here to what I want to accomplish. Any help would be much appreciated.Thank you,Steven [import]uid: 79394 topic_id: 15294 reply_id: 315294[/import]

are you using physics ? then you may try setting gravity to make all the squares fall at once.

try the code below.
[lua]local physics = require(“physics”)
physics.start()
physics.setGravity(0, 0)
local transitions = {}
local function squareSpawn (event)
print(#transitions + 1)
local square = display.newRect(50, 50, 25,25)
square.x = -100
square.y = math.random(0,1024)
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square:removeSelf() end})
physics.addBody(square ,“dynamic”,{isSensor=true})
end
local spawntimer = timer.performWithDelay(math.random(20,35),squareSpawn,0)

local function cancelTransitions()
timer.cancel(spawntimer)
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end
physics.setGravity(0, 9.8)
end
timer.performWithDelay(6000, cancelTransitions ,1)[/lua]

if you don’t want to use physics then u can give transition function also.in that case you have to make each square inan array so that we can handle each of them separately. let me know if you want further help in this.
:slight_smile: [import]uid: 71210 topic_id: 15294 reply_id: 56443[/import]

Hi Renjith,

Nice to hear from u:) Your example is very cool. However, I can’t use physics in this case, as the transition of my squares (the enemies) must match those of my player and background, which have already been coded as conventional transitions. Thus I’m going to have to make each square in an array, like you said. How would you code this? I think the info at the link I mentioned earlier shows you one way, but I’m having problems figuring out which parts of it to use. Hope you can clear things up for me!

Much thanks,
Steven [import]uid: 79394 topic_id: 15294 reply_id: 56449[/import]

just hold on for a few minutes I will code it and send to you… :slight_smile: [import]uid: 71210 topic_id: 15294 reply_id: 56451[/import]

:slight_smile: [import]uid: 79394 topic_id: 15294 reply_id: 56455[/import]

here you go :slight_smile:
[lua]local transitions = {}
local squares = {}

local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = -100
square.y = math.random(0,1024)
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square:removeSelf() end})
return square
end

local k = 1
local function spawnSquares()
squares[k] = squareSpawn()
k=k+1
end
local spawntimer = timer.performWithDelay(math.random(20,35),spawnSquares,0)

local function cancelTransitions()
timer.cancel(spawntimer)
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end

for l=1,#squares do
if squares[l] then
transition.to(squares[l], {time = 1000, delay = 0, y = 920})
end
end
end
timer.performWithDelay(3000, cancelTransitions ,1)[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56456[/import]

just add removeself() for the last transition also. otherwise those squares will be left as used.
[lua]transition.to(squares[l], {time = 1000, delay = 0, y = 920, onComplete=function() squares[l]:removeSelf() end})[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56457[/import]

Thanks for the getting that out so quickly! Right now, the squares are converging to the y = 920 coordinate, rather than all moving + 920 units. I tried tweaking the code to:

transition.to(squares[l], {time = 1000, delay = 0, y = squares[l].y + 920})[/code]..but this wasn't correct. [import]uid: 79394 topic_id: 15294 reply_id: 56461[/import]

…I’m sure I could figure out how to tweak it for the desired effect with just a brief explanation of how your code works, do you mind throwing in a few comments to help me grasp the concept? Even the tiniest bit of info would really be helpful to a first-timer like myself:) [import]uid: 79394 topic_id: 15294 reply_id: 56463[/import]

it will show an error when we try to use y=square[l].y + 920 as some items from the square table might have removed already by the previous transition (one which move objects from left to right).

so just a small tweak will do the job
see the code below…

[lua]local transitions = {}
local squares = {}

local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = 100
square.y = math.random(0,1024)
square.num = num
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square:removeSelf() ;square = nil; end})
return square
end

local k = 1
local function spawnSquares()
squares[k] = squareSpawn()
k=k+1
end
local spawntimer = timer.performWithDelay(math.random(20,35),spawnSquares,0)

local function cancelTransitions()
timer.cancel(spawntimer)
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end

for l=1,#squares do
if squares[l].y then
transition.to(squares[l], {time = 1000, delay = 0, y = squares[l].y + 920, onComplete = function() squares[l]:removeSelf() end})
end
end
end
timer.performWithDelay(3000, cancelTransitions ,1)[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56464[/import]

sorry… :wink:
see the commented code…let me know if u have any doubts…
[lua]–creating a table for storing transitions
–we need to stop all the transitions before making the objects fall
local transitions = {}

–table to store handle for indicidual squares
local squares = {}
–this function spawns objects
– inside this we create local object square. it got individual existance thats how square:removeSelf() works inside the transition.to
– if we use a table inside this function to store individual squares square[i]:removeSelf() may not work as i might have changed
local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = 100
square.y = math.random(0,1024)
square.num = num
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square:removeSelf() ;square = nil; end})
return square
end

– this calls the function squareSpawn which returns a square object
local k = 1
local function spawnSquares()
squares[k] = squareSpawn()
k=k+1
end
local spawntimer = timer.performWithDelay(math.random(20,35),spawnSquares,0)
–this function cancel all the runnign transitions
– this also transition the objects downwards
local function cancelTransitions()
–cancel the timer we used to spawn objects else it will keep own spawning new squares
timer.cancel(spawntimer)

– cancelling the current runnign transitions --those moving from left to right
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end

– loop through each squares to transition it downwards
for l=1,#squares do
–checking if the square is still there or got removed by the left to right transition
if squares[l].y then
transition.to(squares[l], {time = 1000, delay = 0, y = squares[l].y + 920, onComplete = function() squares[l]:removeSelf() end})
end
end
end

–calling cancelTransitions – u can put this inside any function or button press as you like
timer.performWithDelay(3000, cancelTransitions ,1)[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56466[/import]

Wow, works beautifully! It may be overkill, but I feel like putting this code into an art gallery:)

One last thing, if I wanted to keep the horizontal movement of the squares going even after the y-transition starts, would this be an easy thing to do? If it’s overly complex, I might just not bother…

Once again, thank-you!

Steven
[import]uid: 79394 topic_id: 15294 reply_id: 56467[/import]

I din’t get what u mean… did u mean to say that squares keep on coming after the current squares fell down ?
in that case you just need to remove the line timer.cancel(spawntimer) from function cancelTransitions.

:slight_smile: [import]uid: 71210 topic_id: 15294 reply_id: 56468[/import]

No no, the squares stop spawning as they should, I just wanted the squares to keep moving to the right as they fell. Once I read your commented version, I can see what chunk I need to remove to get this effect:

for i=1,#transitions do if transitions[i] then transition.cancel(transitions[i]) end end[/code]So now everything is perfect! Can't thank you enough, Renjith, you are the man!Cheers!Steven [import]uid: 79394 topic_id: 15294 reply_id: 56471[/import]

you may get some error (check ur console) if you try to do a second transition without finishing the first transition.
you can use the below code to get rid of that.
just a small tweak.

[lua]–creating a table for storing transitions
–we need to stop all the transitions before making the objects fall
local transitions = {}

–table to store handle for indicidual squares
local squares = {}
–this function spawns objects
– inside this we create local object square. it got individual existance thats how square:removeSelf() works inside the transition.to
– if we use a table inside this function to store individual squares square[i]:removeSelf() may not work as i might have changed
local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = 100
square.y = math.random(0,1024)
square.num = num
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() if square.y then square:removeSelf() ;square = nil; end end})
return square
end

– this calls the function squareSpawn which returns a square object
local k = 1
local function spawnSquares()
squares[k] = squareSpawn()
k=k+1
end
local spawntimer = timer.performWithDelay(math.random(20,35),spawnSquares,0)
–this function cancel all the runnign transitions
– this also transition the objects downwards
local function cancelTransitions()
–cancel the timer we used to spawn objects else it will keep own spawning new squares
timer.cancel(spawntimer)
–[[
– cancelling the current runnign transitions --those moving from left to right
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end
–]]

– loop through each squares to transition it downwards
for l=1,#squares do
–checking if the square is still there or got removed by the left to right transition
if squares[l].y then
transition.to(squares[l], {time = 1000, delay = 0, y = squares[l].y + 920, onComplete = function() if squares[l].y then squares[l]:removeSelf() end end})
end
end
end

–calling cancelTransitions – u can put this inside any function or button press as you like
timer.performWithDelay(3000, cancelTransitions ,1)[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56474[/import]

Whew! Good thing you caught that, I was so busy marvelling at the effect that I didn’t bother to check the output panel:) I see the tweak you made to the removeSelf function, but when I run the new code I’m still getting the error msg… Hmm, I’ll run it a few more times, maybe I’m mistaken? [import]uid: 79394 topic_id: 15294 reply_id: 56475[/import]

yes…am also getting that error…
will look in to that…
i tried canceling the old transition and setting x and y in new transition . try it ans see whether it will serve ur purpose
[lua]–creating a table for storing transitions
–we need to stop all the transitions before making the objects fall
local transitions = {}

–table to store handle for indicidual squares
local squares = {}

–this function spawns objects
– inside this we create local object square. it got individual existance thats how square:removeSelf() works inside the transition.to
– if we use a table inside this function to store individual squares square[i]:removeSelf() may not work as i might have changed
local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = 100
square.y = math.random(0,1024)
square.num = num
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() if square.y then square:removeSelf() ;square = nil; end end})
return square
end

– this calls the function squareSpawn which returns a square object
local k = 1
local function spawnSquares()
squares[k] = squareSpawn()
k=k+1
end
local spawntimer = timer.performWithDelay(math.random(20,35),spawnSquares,0)

–this function cancel all the runnign transitions
– this also transition the objects downwards
local function cancelTransitions()
–cancel the timer we used to spawn objects else it will keep own spawning new squares
timer.cancel(spawntimer)

– cancelling the current runnign transitions --those moving from left to right
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
end
end

– loop through each squares to transition it downwards
for l=1,#squares do
–checking if the square is still there or got removed by the left to right transition
if squares[l].y then
transition.to(squares[l], {time = 1000, delay = 0, y = squares[l].y + 920, x = squares[l].x + 500,onComplete = function() if squares[l].y then squares[l]:removeSelf() ;squares[l] = nil end end})
end
end
end

–calling cancelTransitions – u can put this inside any function or button press as you like
timer.performWithDelay(3000, cancelTransitions ,1)[/lua] [import]uid: 71210 topic_id: 15294 reply_id: 56477[/import]

Yup, that worked, with no errors!

Okay, I don’t know if I should even bother at this point, as I’ve already gotten a ton of help from you already, but I just realized I probably need to keep the squares spawning all the way through to the end of the fall transition, as it looks wrong for the squares to suddenly stop appearing. This is because the squares represent traffic, and traffic doesn’t really stop. The idea is to simulate looking down at highway, and the transition is to simulate a camera move to an adjacent highway. The effect I’m going for is to take a moving “river” of squares, and transition it downwards til it is off-screen (it is at this point that I would like to end the spawn function). I have a feeling it may take some work to achieve this, and my brain is rather cooked for now, so I’ll bring it up at a later date. In the meantime, much appreciation for all your help to this point.

Deepest thanks,
Steven [import]uid: 79394 topic_id: 15294 reply_id: 56493[/import]

Well, your explanation provides more information, and makes me wonder if you can’t do it in an alternate way.

If you create all the squares, and instead of assigning the squares to an array and stopping existing transitions and starting new transitions try this out.

What I am doing is adding all the squares to a display group, and after 3 seconds, I transition the display group until it is off screen.

Functionally the same as above…just a different method…
[lua]local function main()
–forward declaration of the table, so it is visible.
local spawnedGroup = display.newGroup()
local transitions = {}
local timers = {}

local function squareSpawn (event)
local square = display.newRect(50, 50, 25,25)
square.x = -100
square.y = math.random(0,1024)
transitions[#transitions + 1] = transition.to(square, {time = 1500, delay = 0, x = square.x + 968, onComplete=function() square :removeSelf() end})
spawnedGroup:insert(square)
end

local cleanUp = function()
–cancel and nil all the transitions
for i=1,#transitions do
if transitions[i] then
transition.cancel(transitions[i])
transitions[i] = nil
end
end
–cancel and nil all the timers
for i=1,#timers do
if timers[i] then
timer.cancel(timers[i])
timers[i] = nil
end
end
display.remove(spawnedGroup)
end

local moveCamera = function()
transitions[#transition + 1] = transition.to(spawnedGroup, {time = 1000, y = spawnedGroup.y + 1200, onComplete = cleanUp})
end

timers[#timers + 1] = timer.performWithDelay(math.random(20,35),squareSpawn,0)
timers[#timers + 1] = timer.performWithDelay(3000, moveCamera, 0)
end

main()[/lua]
[import]uid: 5317 topic_id: 15294 reply_id: 56514[/import]

Wow, that’s a beautiful bunch of code, works perfectly! Thanks so much mike4 for putting that forward, it’s exactly what I needed, and thank you Renjith, once again, for getting me to this point, I apologize for not having a clearer explanation of what I was after earlier!

Much appreciation,
Steven [import]uid: 79394 topic_id: 15294 reply_id: 56572[/import]