Timers and enterFrame listener problem

I am having a problem with timers and my “enterFrame” Runtime listener not working.

I have my code structured using composer and in such a way that in my scene:create function I have two things

timer.performWithDelay(500, spawnEnemies, -1)

Runtime:addEventListener(“enterFrame”, updateGame)

I tried putting them in scene:show, but that didn’t work either

All works fine in the simulator. Is anybody else having this issue? Can anybody help?

**After further testing this seems to happen to anything (timer, transition, touch listener, runtime listener) that is put in the scene:create or scene:show. If I put the timer in another module, it works.

I’d still like to know if there is a way to fix this.

Can you post your code?   Just as a practical thing, you shouldn’t start timers and enterScene things in scene:create() since the scene isn’t on the screen yet. 

Hi Rob,

Thanks for that. I didn’t realise that about scene:create(). So what would be the best way to immediately start a timer, transition or listener?

Here’s my code.

local composer = require( "composer" ) local scene = composer.newScene()   local playerMgr = require("classes.playerClass") local shieldMgr = require("classes.shieldClass") local enemyMgr = require("classes.enemyClass")   local playerGroup = display.newGroup() local enemyGroup = display.newGroup()   ----------------- Updates Game local updateGame = function () playerMgr.updatePlayer() end   function scene:create(event) local sceneGroup = self.view   sceneGroup:insert(playerGroup) sceneGroup:insert(enemyGroup)   local player = playerMgr.createPlayer({objGroup = playerGroup}) local shield = shieldMgr.createShield({objGroup = playerGroup})   ----------------- Spawn Enemies local spawnEnemies = function() if (math.random(10) \> 4) then local invader = enemyMgr.createEnemy({objGroup = enemyGroup}) end end   local spawnTimer = timer.performWithDelay(500, spawnEnemies, -1) Runtime:addEventListener("enterFrame", updateGame) end   scene:addEventListener("create", scene)   return scene

You need to define the scene:show( event ) function and add it’s listener.  Inside of scene.show, during the will phase turn everything on:

function scene:show( event )

     local sceneGroup = self.view

     local phase = event.phase

     if event.phase == “did” then

         spawnTimer = timer.performWithDelay(500, spawnEnemies, -1)
         Runtime:addEventListener(“enterFrame”, updateGame)

     end

end

scene:addEventListener(“show”, scene)

Because of scoping issues, you probably should declare spawnTimer as local at the top of the module somewhere before the scene:create() function:

local spawnTimer

The next issue is that spawnEnemies is a local function to scene:create(), so scene:show() doesn’t have access to it.  You should move it outside of the scene:create() function like you do with updateFunction()

Rob

That all worked perfectly.

Thank you so much Rob.

Can you post your code?   Just as a practical thing, you shouldn’t start timers and enterScene things in scene:create() since the scene isn’t on the screen yet. 

Hi Rob,

Thanks for that. I didn’t realise that about scene:create(). So what would be the best way to immediately start a timer, transition or listener?

Here’s my code.

local composer = require( "composer" ) local scene = composer.newScene()   local playerMgr = require("classes.playerClass") local shieldMgr = require("classes.shieldClass") local enemyMgr = require("classes.enemyClass")   local playerGroup = display.newGroup() local enemyGroup = display.newGroup()   ----------------- Updates Game local updateGame = function () playerMgr.updatePlayer() end   function scene:create(event) local sceneGroup = self.view   sceneGroup:insert(playerGroup) sceneGroup:insert(enemyGroup)   local player = playerMgr.createPlayer({objGroup = playerGroup}) local shield = shieldMgr.createShield({objGroup = playerGroup})   ----------------- Spawn Enemies local spawnEnemies = function() if (math.random(10) \> 4) then local invader = enemyMgr.createEnemy({objGroup = enemyGroup}) end end   local spawnTimer = timer.performWithDelay(500, spawnEnemies, -1) Runtime:addEventListener("enterFrame", updateGame) end   scene:addEventListener("create", scene)   return scene

You need to define the scene:show( event ) function and add it’s listener.  Inside of scene.show, during the will phase turn everything on:

function scene:show( event )

     local sceneGroup = self.view

     local phase = event.phase

     if event.phase == “did” then

         spawnTimer = timer.performWithDelay(500, spawnEnemies, -1)
         Runtime:addEventListener(“enterFrame”, updateGame)

     end

end

scene:addEventListener(“show”, scene)

Because of scoping issues, you probably should declare spawnTimer as local at the top of the module somewhere before the scene:create() function:

local spawnTimer

The next issue is that spawnEnemies is a local function to scene:create(), so scene:show() doesn’t have access to it.  You should move it outside of the scene:create() function like you do with updateFunction()

Rob

That all worked perfectly.

Thank you so much Rob.