Strange problem...

I’m trying to spawn a single asteroid every second that falls from the top of the screen to the bottom. Everything is working, but for whatever reason its spawns 4 asteroids every time instead of one… I don’t see where I have 4 asteroids spawning. I am using composer, this is in my game.lua file.

Anyone see what is wrong in the code?

Any tips would be great!

Bolded parts are asteroid spawn:

local composer = require( “composer” )
local scene = composer.newScene()

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

local mydata = require( “mydata” )

local W = display.contentWidth
local H = display.contentHeight

mydata.score=0

function asteroidSpawn()
  asteroid = display.newImage(“Images/ast.png”)
  asteroid.width = 64
  asteroid.height = 64
  asteroid.x = math.random(128,W-128)
  asteroid.y = - 256
  physics.addBody(asteroid, {0,0,0})
  asteroid:setLinearVelocity(0,300)
  asteroid:addEventListener(“tap”, myTapListener)
  --asteroid.collision = astCollision
  --asteroid:addEventListener(“collision”, asteroid)
  --asteroid.type = “asteroid”
 end

function myTapListener(event)
 if (event.target) then
  print(“pow!”)
 return true
end
end

function scene:create( event )

 local sceneGroup = self.view

 composer.removeScene(“start”)

 background = display.newImageRect(“Images/bg1a.png”, 480,320)
 background.anchorX = 0.5
 background.anchorY = 1
 background.x = display.contentCenterX
 background.y = display.contentHeight
 sceneGroup:insert(background)

end

function scene:show( event )

 local sceneGroup = self.view

 timer.performWithDelay(1000,asteroidSpawn,0)

end

function scene:hide( event )

 local sceneGroup = self.view

end

function scene:destroy( event )

 local sceneGroup = self.view

end

scene:addEventListener( “create”, scene )
scene:addEventListener( “show”, scene )
scene:addEventListener( “hide”, scene )
scene:addEventListener( “destroy”, scene )

return scene

Scene:show and scene:hide event handlers both have two phases when they are called. If you don’t filter out the phase then your code will be executed twice when the scene loads or when the scene exits the screen.

Just put this in your event handlers

local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end

That would explain why you get more than one asteroid, but I’m not sure why you would get four… Are you calling scene:show() yourself?

Appreciate the input.

I’m confused about what you are saying… I should put the timer in the code you said to use?

local phase = event.phase

    if (phase == “will”) then

      timer.performWithDelay(1000,asteroidSpawn,0)

    elseif (phase == “did”) then

end

end

and then that block of code goes inside of the scene:show(event)? So confused.

I don’t get what that is doing…

I’m not calling scene:show() myself, no.

It’s in the Composer tutorial.

Basically, when you transition to your new scene, scene:show gets called with event.phase = “will”. This code will excute before your scene actually shows up on the screen.

Next, after your scene finishes the transition and is fully on screen, scene:show gets called again with event.phase = “did”. That’s where you want to begin spawning your asteroids.

So to sum it up:

function scene:show( event ) local phase = event.phase if ( phase == "will" ) then -- Scene is still off screen elseif ( phase == "did" ) then -- Now spawn your asteroids end end

If you’re still confused then I suggest setting break points in your code and debugging so you can inspect what’s happening line by line.

Awesome! That makes sense, I had overlooked that tutorial. Thanks for the help.

Now I’m only getting 2 asteroids spawning each time instead of the one that should spawn, no idea where that double is coming from.

Edit: Figured out the double spawn, it was from the timer being in the show() function. I put the timer up above with all of the local variables and functions and it fixed it.

Scene:show and scene:hide event handlers both have two phases when they are called. If you don’t filter out the phase then your code will be executed twice when the scene loads or when the scene exits the screen.

Just put this in your event handlers

local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. end

That would explain why you get more than one asteroid, but I’m not sure why you would get four… Are you calling scene:show() yourself?

Appreciate the input.

I’m confused about what you are saying… I should put the timer in the code you said to use?

local phase = event.phase

    if (phase == “will”) then

      timer.performWithDelay(1000,asteroidSpawn,0)

    elseif (phase == “did”) then

end

end

and then that block of code goes inside of the scene:show(event)? So confused.

I don’t get what that is doing…

I’m not calling scene:show() myself, no.

It’s in the Composer tutorial.

Basically, when you transition to your new scene, scene:show gets called with event.phase = “will”. This code will excute before your scene actually shows up on the screen.

Next, after your scene finishes the transition and is fully on screen, scene:show gets called again with event.phase = “did”. That’s where you want to begin spawning your asteroids.

So to sum it up:

function scene:show( event ) local phase = event.phase if ( phase == "will" ) then -- Scene is still off screen elseif ( phase == "did" ) then -- Now spawn your asteroids end end

If you’re still confused then I suggest setting break points in your code and debugging so you can inspect what’s happening line by line.

Awesome! That makes sense, I had overlooked that tutorial. Thanks for the help.

Now I’m only getting 2 asteroids spawning each time instead of the one that should spawn, no idea where that double is coming from.

Edit: Figured out the double spawn, it was from the timer being in the show() function. I put the timer up above with all of the local variables and functions and it fixed it.