performWithDelay not repeating...

Hello,

I have an enemy spawner function being called with performWithDelay.  I am passing the function name and the number of enemies to spawn, but for some reason the function only runs once… any ideas on why?

local function spawnEnemies(enemyType) print("Running spawnEnemies Function") local path = gameBoard.\_path -- local random = random local enemyType = enemyType local params = {spawnX=x, spawnY=y, enemyType=enemyType, path=path} --EnemyTable[#EnemyTable+1] = Enemy:new(group, params) local myEnemy = Enemy:new(group,params) -- EnemyTable[#EnemyTable]:ChangeSpeed() --print("Enemy Built!") myEnemy=nil end print("Spawning: "..totalEnemies.." level "..enemyType.." enemies.") local mySpawnEnemies = spawnEnemies(enemyType) local spawnEnemiesTmr = timer.performWithDelay(1000, mySpawnEnemies, totalEnemies)

The output shows:

Spawning: 10 level 1 enemies.    
Running spawnEnemies Function  

Where it should show something like:

Spawning: 10 level 1 enemies.    
Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

Running spawnEnemies Function

I just tested sending a number instead of totalEnemies and it doesn’t repeat either… so there is something wrong with the way I’m doing things… the code below is the big picture, hopefully it helps…

local thisLevel = { { --Wave 1 {EnemyType=1, EnemyQuantity=10} }, { --Wave 2 {EnemyType=1, EnemyQuantity=10}, {EnemyType=2, EnemyQuantity=3} }, { --Wave 3 {EnemyType=1, EnemyQuantity=10}, {EnemyType=2, EnemyQuantity=10}, {EnemyType=3, EnemyQuantity=2} } } player = require('playerVars') -- include Corona's "physics" library local physics = require "physics" physics.start(); physics.pause() physics.setGravity( 0, 0 ) --physics.setDrawMode( "debug" ) --physics.setDrawMode("hybrid") -------------------------------------------- -- forward declarations and other locals local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth\*0.5 local gameBoard ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- ----------------------------------------------------------------------------------------- -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view --local EnemyTable={} local waveDelay=200 local currentWave = 0 local currentGroup = 1 local gameBoard= Board:new(group) --Spawn Enemies local x local y for node, count in gameBoard.\_path:nodes() do --print(('Step: %d - x: %d - y: %d'):format(count, node:getX(), node:getY())) if count==1 then x = node:getX()\*32 y = node:getY()\*32 end break end -- local random = math.random local function spawnEnemies(enemyType) print("Running spawnEnemies Function") local path = gameBoard.\_path -- local random = random local enemyType = enemyType local params = {spawnX=x, spawnY=y, enemyType=enemyType, path=path} --EnemyTable[#EnemyTable+1] = Enemy:new(group, params) local myEnemy = Enemy:new(group,params) -- EnemyTable[#EnemyTable]:ChangeSpeed() --print("Enemy Built!") myEnemy=nil print("DONE Running spawnEnemies Function") end local function doGroup() print("Running doGroup Function") local thisLevel = thisLevel local currentWave = currentWave local currentGroup = currentGroup currentGroup = currentGroup + 1 if currentGroup \> #thisLevel[currentWave] then currentGroup = 1 myCurrentGroup = currentGroup end local totalEnemyGroups = #thisLevel[currentWave] local totalEnemies = thisLevel[currentWave][currentGroup].EnemyQuantity --local totalEnemies = thisLevel[currentWave][currentGroup].EnemyQuantity local enemyType = thisLevel[currentWave][currentGroup].EnemyType print("Spawning: "..totalEnemies.." level "..enemyType.." enemies.") local mySpawnEnemies = spawnEnemies(enemyType) local spawnEnemiesTmr = timer.performWithDelay(1000, mySpawnEnemies, 10) print("DONE Running doGroup Function") end local function doWave() print("Running doWave Function") currentWave = currentWave+1 local thisLevel = thisLevel local currentWave = currentWave local myCurrentGroup = currentGroup print("Current Wave: "..currentWave.." Current Group: "..myCurrentGroup) local totalEnemyGroups = #thisLevel[currentWave] print("Total Groups in this wave: "..totalEnemyGroups) local totalEnemies = thisLevel[currentWave][myCurrentGroup].EnemyQuantity print("Total Enemies in this Group: "..totalEnemies) local totalTimeDelay = totalEnemies \* 1000 print ("Total Time Delay is: "..totalTimeDelay) local doGroupTmr = timer.performWithDelay(totalTimeDelay, doGroup, totalEnemyGroups) end local doWavesTmr = timer.performWithDelay(2000, doWave, 1) local doWavesTmr = timer.performWithDelay(13000, doWave, #thisLevel - 1) end

The problem is this line:

[lua]

local mySpawnEnemies = spawnEnemies(enemyType)

[/lua]

It looks like what you’re trying to do is make mySpawnEnemies a shorthand way of referring to the function call spawnEnemies(enemyType).  But what you’ve actually done is assign to mySpawnEnemies the return value of spawnEnemies(enemyType).  Since that function doesn’t return anything, mySpawnEnemies is nil, and hence the timer doesn’t do anything.  You still see the print statement appear one time, because mySpawnEnemies(enemyType) gets called via this statement one time.

Instead, what you probably want to do is use a closure, like this:

[lua]

local mySpawnEnemies = function() spawnEnemies(enemyType) end

[/lua]

Hope this helps.

  • Andrew

Can your spawnEnemies() function run without an enemyType? Because that’s what you’re doing with timer.performWithDelay.

If you want to specify an enemyType you should use a closure.

timer.performWithDelay(1000, function() dothis(14) end, 10)

I just tested sending a number instead of totalEnemies and it doesn’t repeat either… so there is something wrong with the way I’m doing things… the code below is the big picture, hopefully it helps…

local thisLevel = { { --Wave 1 {EnemyType=1, EnemyQuantity=10} }, { --Wave 2 {EnemyType=1, EnemyQuantity=10}, {EnemyType=2, EnemyQuantity=3} }, { --Wave 3 {EnemyType=1, EnemyQuantity=10}, {EnemyType=2, EnemyQuantity=10}, {EnemyType=3, EnemyQuantity=2} } } player = require('playerVars') -- include Corona's "physics" library local physics = require "physics" physics.start(); physics.pause() physics.setGravity( 0, 0 ) --physics.setDrawMode( "debug" ) --physics.setDrawMode("hybrid") -------------------------------------------- -- forward declarations and other locals local screenW, screenH, halfW = display.contentWidth, display.contentHeight, display.contentWidth\*0.5 local gameBoard ----------------------------------------------------------------------------------------- -- BEGINNING OF YOUR IMPLEMENTATION -- -- NOTE: Code outside of listener functions (below) will only be executed once, -- unless storyboard.removeScene() is called. -- ----------------------------------------------------------------------------------------- -- Called when the scene's view does not exist: function scene:createScene( event ) local group = self.view --local EnemyTable={} local waveDelay=200 local currentWave = 0 local currentGroup = 1 local gameBoard= Board:new(group) --Spawn Enemies local x local y for node, count in gameBoard.\_path:nodes() do --print(('Step: %d - x: %d - y: %d'):format(count, node:getX(), node:getY())) if count==1 then x = node:getX()\*32 y = node:getY()\*32 end break end -- local random = math.random local function spawnEnemies(enemyType) print("Running spawnEnemies Function") local path = gameBoard.\_path -- local random = random local enemyType = enemyType local params = {spawnX=x, spawnY=y, enemyType=enemyType, path=path} --EnemyTable[#EnemyTable+1] = Enemy:new(group, params) local myEnemy = Enemy:new(group,params) -- EnemyTable[#EnemyTable]:ChangeSpeed() --print("Enemy Built!") myEnemy=nil print("DONE Running spawnEnemies Function") end local function doGroup() print("Running doGroup Function") local thisLevel = thisLevel local currentWave = currentWave local currentGroup = currentGroup currentGroup = currentGroup + 1 if currentGroup \> #thisLevel[currentWave] then currentGroup = 1 myCurrentGroup = currentGroup end local totalEnemyGroups = #thisLevel[currentWave] local totalEnemies = thisLevel[currentWave][currentGroup].EnemyQuantity --local totalEnemies = thisLevel[currentWave][currentGroup].EnemyQuantity local enemyType = thisLevel[currentWave][currentGroup].EnemyType print("Spawning: "..totalEnemies.." level "..enemyType.." enemies.") local mySpawnEnemies = spawnEnemies(enemyType) local spawnEnemiesTmr = timer.performWithDelay(1000, mySpawnEnemies, 10) print("DONE Running doGroup Function") end local function doWave() print("Running doWave Function") currentWave = currentWave+1 local thisLevel = thisLevel local currentWave = currentWave local myCurrentGroup = currentGroup print("Current Wave: "..currentWave.." Current Group: "..myCurrentGroup) local totalEnemyGroups = #thisLevel[currentWave] print("Total Groups in this wave: "..totalEnemyGroups) local totalEnemies = thisLevel[currentWave][myCurrentGroup].EnemyQuantity print("Total Enemies in this Group: "..totalEnemies) local totalTimeDelay = totalEnemies \* 1000 print ("Total Time Delay is: "..totalTimeDelay) local doGroupTmr = timer.performWithDelay(totalTimeDelay, doGroup, totalEnemyGroups) end local doWavesTmr = timer.performWithDelay(2000, doWave, 1) local doWavesTmr = timer.performWithDelay(13000, doWave, #thisLevel - 1) end

The problem is this line:

[lua]

local mySpawnEnemies = spawnEnemies(enemyType)

[/lua]

It looks like what you’re trying to do is make mySpawnEnemies a shorthand way of referring to the function call spawnEnemies(enemyType).  But what you’ve actually done is assign to mySpawnEnemies the return value of spawnEnemies(enemyType).  Since that function doesn’t return anything, mySpawnEnemies is nil, and hence the timer doesn’t do anything.  You still see the print statement appear one time, because mySpawnEnemies(enemyType) gets called via this statement one time.

Instead, what you probably want to do is use a closure, like this:

[lua]

local mySpawnEnemies = function() spawnEnemies(enemyType) end

[/lua]

Hope this helps.

  • Andrew

Can your spawnEnemies() function run without an enemyType? Because that’s what you’re doing with timer.performWithDelay.

If you want to specify an enemyType you should use a closure.

timer.performWithDelay(1000, function() dothis(14) end, 10)