Change speed of all spawned objects on screen?

Hi

I’m writing a program which spawns objects, moves them down the screen
and deletes them when they get to the bottom.

I want to change the speed of all the spawned objects at once. My current code only changes the speed of newly spawned objects.

How can I get the objects to check their speed against a variable each frame and adjust it, so they all speed up/slow down at the same time?

Heres my code:

[code]

physics = require(“physics”)
physics.start()
physics.setGravity(0,0)

_H = display.contentHeight;
_W = display.contentWidth;
mRand = math.random;
terrainspeed = 200
tsmod = 0
craterRate = 1000
local hitdet = display.newRect(0, 0, _W, 5)
hitdet.x = _W / 2
hitdet.y = _H - 5
hitdet:setFillColor(0, 0, 255)
physics.addBody(hitdet, “static”, {density = 1.0, friction = 0, bounce = 0, isSensor =true})
hitdet.myName = “hitDet”

function tsmodifier() --picks a random value by which to modify terrainspeed
tsmod = mRand(0, 50)
end

function spawnCrater() – spawns a crater, checks its y position and moves it if necessary.
crater = display.newCircle (mRand(0, _W), _H / _H, mRand(30, 100))
physics.addBody( crater, { friction=0, bounce=0, radius = crater.radius} )
crater.isSensor = true
crater.myName = “Crater”

function craterspeed(event)
crater:setLinearVelocity( 0, terrainspeed + tsmod)
end

Runtime:addEventListener(“enterFrame”, craterspeed)

end
local function onLocalCollision( self, event )
if ( event.phase == “began” ) then

print( self.myName … ": collision began with " … event.other.myName )
local function removecrater()
event.other:removeSelf()
end

Timer4 = timer.performWithDelay(1,removecrater, 1)

elseif ( event.phase == “ended” ) then

print( self.myName … ": collision ended with " … event.other.myName )

end
end
hitdet.collision = onLocalCollision
hitdet:addEventListener( “collision”, hitdet )

Timer1 = timer.performWithDelay(craterRate, spawnCrater, 0)
Timer3 = timer.performWithDelay(5000,tsmodifier, 0)
``

Thanks [import]uid: 67933 topic_id: 13452 reply_id: 313452[/import]

Put each spawned object into a table then create a loop to go through each item in the table and change it’s speed property.

Examlpe:

[lua] local spawnedItems = {}

for i=1, #spawnedItems do
spawnedItems[i].speed = 500
end

OR
for i=1, #spawnedItems do
function craterspeed(event)
spawnedItems[i]:setLinearVelocity( 0, terrainspeed + tsmod)
end
end[/lua] [import]uid: 63320 topic_id: 13452 reply_id: 49401[/import]

Fantastic! Thanks for the prompt reply.

My Spawncrater function now looks like this.

function spawnCrater() -- spawns a crater, checks its y position and moves it if necessary.  
  
 --local spawnedItems = {}  
  
 crater = display.newCircle (mRand(0, \_W), \_H / \_H, mRand(30, 100))   
 physics.addBody( crater, { friction=0, bounce=0, radius = crater.radius} )  
 crater.isSensor = true  
 crater.myName = "Crater"  
 table.insert(spawnedItems, crater);  
  
  
 for i=1, #spawnedItems do  
 function craterspeed(event)  
 spawnedItems[i]:setLinearVelocity( 0, terrainspeed + tsmod)  
 end  
 end  
 Runtime:addEventListener("enterFrame", craterspeed)   
end  

If you run it at the moment, the first crater deletes on collision with the rectangle at the bottom of the screen, then each subsequent crater registers the collision but doesn’t delete.

Is it because I’m not removing it from the table when it’s deleted, or some problem with the runtime listener?

Thanks [import]uid: 67933 topic_id: 13452 reply_id: 49436[/import]

Try removing it from the table as well as off of the screen. If that doesn’t work, could you post some more code so I can see the rest of the project?

EDIT: I forgot to to look at your original post :P. I’ll work up a solution right now. [import]uid: 63320 topic_id: 13452 reply_id: 49545[/import]

Ok so I figured it out. If you look through the code you can see how the speed change is ran.

[lua]physics = require(“physics”)
physics.start()
physics.setGravity(0,0)

_H = display.contentHeight;
_W = display.contentWidth;
mRand = math.random;
terrainspeed = 200
tsmod = 0
craterRate = 1000
local crateNum = 0

local hitdet = display.newRect(0, 0, _W, 5)
hitdet.x = _W / 2
hitdet.y = _H - 5
hitdet:setFillColor(0, 0, 255)
physics.addBody(hitdet, “static”, {density = 1.0, friction = 0, bounce = 0, isSensor =true})
hitdet.myName = “hitDet”

function tsmodifier() --picks a random value by which to modify terrainspeed
tsmod = mRand(0, 200)
changeCrateSpeed(tsmod)
print("Speed changed to "…tsmod)
end

local crateGroup = display.newGroup()

function spawnCrater() – spawns a crater, checks its y position and moves it if necessary.
crateNum = crateNum + 1
crater = display.newCircle (mRand(0, _W), _H / _H, mRand(30, 100))
physics.addBody( crater, { friction=0, bounce=0, radius = crater.radius} )
crater.isSensor = true
crater.myName = “Crater”…crateNum

crateGroup:insert(crater)

function craterspeed(event)
crater:setLinearVelocity( 0, terrainspeed + tsmod)
end

Runtime:addEventListener(“enterFrame”, craterspeed)
end

local function onLocalCollision( self, event )
if ( event.phase == “began” ) then

print( self.myName … ": collision began with " … event.other.myName )
local function removecrater()
event.other:removeSelf()
end

Timer4 = timer.performWithDelay(1,removecrater, 1)

elseif ( event.phase == “ended” ) then

print( self.myName … ": collision ended with " … event.other.myName )

end
end

function changeCrateSpeed(speed)
for i=1, #crateGroup do
crateGroup(i):setLinearVelocity( 0, terrainspeed + speed)
end
end

hitdet.collision = onLocalCollision
hitdet:addEventListener( “collision”, hitdet )

Timer1 = timer.performWithDelay(craterRate, spawnCrater, 0)
Timer3 = timer.performWithDelay(5000,tsmodifier, 0)[/lua] [import]uid: 63320 topic_id: 13452 reply_id: 49550[/import]

Hey dacriburdan.

Firstly, thank you for all your help, it’s really useful to see how you’ve put the code together.

It may be easier to explain how the code will be implemented in the finished app.

Each of the circles will be a crater, which a buggy has to steer around. If the buggy hits a crater it’s game over.

The buggy is controlled with the accelerometer. The x axis moves the buggy left and right, and the y axis controls the speed at which the terrain moves down the screen, (to simulate acceleration).

Your code is great, and the craters all finally delete on impact with the bar at the bottom of the screen, but it still only changes the speed of the craters as they spawn and not all the craters on screen at the same time.

Shouldn’t this part of the code set every object in the table to the same speed?

function changeCrateSpeed(speed)  
 for i=1, #crateGroup do  
 crateGroup(i):setLinearVelocity( 0, terrainspeed + tsmod)  
 end  
end  

Is there any way to get all the craters on screen to move at the same speed, and change that speed by changing a variable (tsmod)?

Thanks again.

Dan [import]uid: 67933 topic_id: 13452 reply_id: 49638[/import]

In my testing, the function below did change the speed of all the objects currently on the screen as well as the objects that have yet to spawn.

[lua]function changeCrateSpeed(speed)
for i=1, #crateGroup do
crateGroup(i):setLinearVelocity( 0, terrainspeed + speed)
end
end[/lua] [import]uid: 63320 topic_id: 13452 reply_id: 49647[/import]

Hmmm, that’s very odd.

To clarify, I’m running the code you posted at reply #4. Can you confirm that your code is exactly the same?

Is there any way that 2 identical versions of the same code could give different results in simulator?

I’m using simulator 2011.8.2

Can anyone else test the code to try and isolate whatever’s causing the problem please? [import]uid: 67933 topic_id: 13452 reply_id: 49682[/import]

Ok, so I’ve been playing around with the code posted at reply#4.

I’ve commented out the runtime listener in the “spawnCrater” function as follows:

function spawnCrater() -- spawns a crater, checks its y position and moves it if necessary.  
 crateNum = crateNum + 1  
 crater = display.newCircle (mRand(0, \_W), \_H / \_H, mRand(30, 100))   
 physics.addBody( crater, { friction=0, bounce=0, radius = crater.radius} )  
 crater.isSensor = true  
 crater.myName = "Crater"..crateNum  
  
 crateGroup:insert(crater)  
  
 function craterspeed(event)  
 crater:setLinearVelocity( 0, terrainspeed + tsmod)  
 end  
  
 --Runtime:addEventListener("enterFrame", craterspeed)   
end  

Now the craters do not move at all. It seems therefore as if the craters were still getting their speed from:

function craterspeed(event)  
 crater:setLinearVelocity( 0, terrainspeed + tsmod)  
 end  

Instead of dynamically changing speed from:

function changeCrateSpeed(speed)  
 for i=1, #crateGroup do  
 crateGroup(i):setLinearVelocity( 0, terrainspeed + speed)  
 end  
end  

Sorry to keep bothering you, but could you possibly take another look at what is happening, or point me in the right direction if you’re too busy?

Thanks [import]uid: 67933 topic_id: 13452 reply_id: 49861[/import]