Game : if time >= # then new object PROBLEM

Hi, 

I created a game in which there are meteorites that move and just stay alive and not getting hit but I have a problem that, if I manage to solve it, allow me to finish my game totally !!!

When 30 seconds is passed in game (my score will be 30 too) I want a third meteorite appears, however, such as is my code there, the third meteorite bug and begins to move in any direction very quickly. … so there is a problem with my moveMeteor3() function and harder() but I can not seem to solve the …

Can you help me please, I have to project normally on Tuesday and I will like it ended well …

Thank you very much, I attached my code:

--Game scene local composer = require("composer") local scene = composer.newScene() local musicGame = audio.loadStream("musicGame.wav") musicGame = audio.play( musicGame , {loops=200 }) --audio.stop(musicMenu) --Physic function local physics = require ("physics") physics.start () physics.setGravity(0, 0) --physics.setDrawMode("hybrid") local leftWall = display.newRect(0, display.contentCenterY, 1, 700) local rightWall = display.newRect(320, display.contentCenterY, 1, 700) local flooring = display.newRect (display.contentCenterX, 524, 500, 1 ) local ceiling = display.newRect(display.contentCenterX, -44, 500, 1 ) physics.addBody(leftWall, "static", { bounce = 0.1}) physics.addBody(rightWall, "static", { bounce = 0.1}) physics.addBody(ceiling, "static", { bounce = 0.1}) physics.addBody(flooring, "static", { bounce = 0.1}) local armadillo local function spawnMeteor() local meteor = display.newImage("meteor.png") physics.addBody(meteor, "dynamic",{friction = 1.0, radius={200}}) meteor.x, meteor.y = math.random (5, 315), math.random (-40, 200) meteor.myName = "meteor" return meteor end function scene:create(event) local sceneGroup = self.view --Background local background = display.newImage("fond.png", 200, 250, 480, 70) armadillo = display.newImage("arm.png") meteor1 = spawnMeteor() meteor2 = spawnMeteor() meteor3 = spawnMeteor() meteor3.x = -10 gauche = display.newImage("boutongauche.png") droit = display.newImage("boutondroit.png") bas = display.newImage("boutonbas.png") haut = display.newImage("boutonhaut.png") score = 0 scoreTxt = display.newText(score, 300, 30, font, 50) scoreTxt.x = 160 scoreTxt.y = -23 sceneGroup:insert(background) sceneGroup:insert(scoreTxt) sceneGroup:insert(meteor1) sceneGroup:insert(meteor2) sceneGroup:insert(meteor3) sceneGroup:insert(gauche) sceneGroup:insert(droit) sceneGroup:insert(bas) sceneGroup:insert(haut) sceneGroup:insert(armadillo) end function scene:show (event) local phase = event.phase if (phase == "will") then local sceneGroup = self.view \_W = display.contentWidth; \_H = display.contentHeight; motionx = 0; motiony = 0 speed = 3; armadillo.x = 160 armadillo.y = 400 physics.addBody(armadillo, "dynamic",{ bounce =0.8,friction = 1.0}) armadillo.gravityScale = 0 armadillo.isFixedRotation = true armadillo.ID = "arma" armadillo.myName = "player" gauche.x = 50; gauche.y = 460; droit.x = 150; droit.y = 460 bas.x = 100; bas.y = 460 haut.x = 100; haut.y = 410 local meteor1 local meteor2 local meteor3 elseif (phase =="did") then local sceneGroup = self.view local function movearmadillo (event) --if gauche.x == 50 then armadillo.x = armadillo.x + motionx; armadillo.y = armadillo.y + motiony local function stop (event) if event.phase =="ended" then motionx = 0; motiony = 0 end end Runtime:addEventListener("touch", stop ) --end end Runtime:addEventListener("enterFrame", movearmadillo) function gauche:touch() motionx = -speed; end gauche:addEventListener("touch",gauche) function droit:touch() motionx = speed; end droit:addEventListener("touch",droit) function haut:touch() motiony = -speed; end haut:addEventListener("touch", haut) function bas:touch() motiony = speed; end bas:addEventListener("touch", bas) function moveMeteor() transition.to(meteor1, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor}) end moveMeteor() function moveMeteor2() transition.to(meteor2, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor2}) end moveMeteor2() function moveMeteor3() transition.to(meteor3, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor3}) end function harder (event) if score \>= 5 then moveMeteor3() end end Runtime: addEventListener("enterFrame", harder) local function updateScore() score = score + 1 scoreTxt.text = score end scoreTimer = timer.performWithDelay(1000, updateScore, -1) function onCollision(event) if(event.object1.myName == "player" and event.object2.myName == "meteor") or (event.object1.myName == "meteor" and event.object2.myName == "player") or (event.object1.myName == "player" and event.object2.myName == "meteor2") or (event.object1.myName == "meteor2" and event.object2.myName == "player") then print(event.object1.myName, event.object2.myName, score) Runtime:removeEventListener("enterFrame", movearmadillo) composer.gotoScene("gameOver", {effect = "fade", time = 200}) end end Runtime:addEventListener("collision", onCollision) end end function scene:hide (event) local sceneGroup = self.view local phase = event.phase if(phase == "will") then timer.cancel(scoreTimer) audio.pause("musicGame") composer.setVariable("score", score) moveMeteor = false moveMeteor2 = false elseif (phase == "did") then --composer.gotoScene ( "gameOver", {effect = "fade", time = 200}) end end scene:addEventListener("show", scene) scene:addEventListener("create", scene) scene:addEventListener("hide", scene) return scene

My code is not perfect, I am not a professional and this is not really important as long as it works. Moreover, in my code, I want the meteorite appear after 5 seconds so I could quickly see if it works.

Thank you for your help

Lucas

Please, I think it’s easy to solve for someone who knowls well lua’s coding !

Help me !  :frowning:

I think the problem might be here:

        function harder (event)         if score \>= 5 then             moveMeteor3()         end         end         Runtime: addEventListener("enterFrame", harder)

enterFrame listeners trigger 30 or 60 times per second. When you call function harder, you’re calling moveMeteor3() 30 or 60 times per second. This is creating dozens of transitions per second. The solution would be to add a flag variable to say I’ve already started running.

 local meteor3isRunning = false function harder (event) if score \>= 5 and not meteor3isRunning then meteor3isRunning = true moveMeteor3() end end Runtime: addEventListener("enterFrame", harder)

That should help. However there is a more efficient way and and not use an enterFrame at all. At the point in your code where you are adding to the score, you can put in an “if” statement that that says:

if score == 5 then       moveMeteor3() end

That way you are not checking every frame to see if you should start it and checking every frame afterwards for no good use. This way you check only when the score changes.

Rob

Hi Rob,

it works for the first time the program is completed but as soon as I replay the game, I think the score is still considered superior to 5 hit the meteorite appears early on and gets a bugger when the score exceeds 5 … we should destroy the score and then destroy the function moveMeteor3() not to rerun it from the start !

You see how you could do that?

Thank you for helping me !

Lucas

In your scene:show() inside the phase == “will” if, add score = 0

 if (phase == "will") then score = 0 local sceneGroup = self.view

Try that!

It doesn’t work … the same problem ! :confused:

Okay, i don’t really understand why but I find a solution !

I put this in scene:hide()  :

if(phase == "will") then moveMeteor3 = false

and on the gameOver scene i put this in the scene:create () ans not out the scene :

currentscoreTimer = composer.getVariable("score")

Thank you anyway for your help !  :wink:

Be Happy !  :slight_smile:

Bye !

Lucas

moveMeteor3 = nil basically forced Corona to no longer know about that function.

If you do this:

Runtime: addEventListener("enterFrame", harder)

you have to somewhere do:

Runtime: removeEventListener("enterFrame", harder)

Normally you would do that before you call composer.gotoScene() to go to the next scene or in scene:hide()'s “will” phase. Things like Runtime enterFrame listeners, physics, timers and transitions will still want to run when you leave your scene. It’s your responsibility to keep a handle (variable that keeps track of the object) to things you need to remove and then remove them at the appropriate time.

Rob

Rob meant:

Runtime: removeEventListener("enterFrame", harder)

Good catch Jon!

Please, I think it’s easy to solve for someone who knowls well lua’s coding !

Help me !  :frowning:

I think the problem might be here:

        function harder (event)         if score \>= 5 then             moveMeteor3()         end         end         Runtime: addEventListener("enterFrame", harder)

enterFrame listeners trigger 30 or 60 times per second. When you call function harder, you’re calling moveMeteor3() 30 or 60 times per second. This is creating dozens of transitions per second. The solution would be to add a flag variable to say I’ve already started running.

 local meteor3isRunning = false function harder (event) if score \>= 5 and not meteor3isRunning then meteor3isRunning = true moveMeteor3() end end Runtime: addEventListener("enterFrame", harder)

That should help. However there is a more efficient way and and not use an enterFrame at all. At the point in your code where you are adding to the score, you can put in an “if” statement that that says:

if score == 5 then       moveMeteor3() end

That way you are not checking every frame to see if you should start it and checking every frame afterwards for no good use. This way you check only when the score changes.

Rob

Hi Rob,

it works for the first time the program is completed but as soon as I replay the game, I think the score is still considered superior to 5 hit the meteorite appears early on and gets a bugger when the score exceeds 5 … we should destroy the score and then destroy the function moveMeteor3() not to rerun it from the start !

You see how you could do that?

Thank you for helping me !

Lucas

In your scene:show() inside the phase == “will” if, add score = 0

 if (phase == "will") then score = 0 local sceneGroup = self.view

Try that!

It doesn’t work … the same problem ! :confused:

Okay, i don’t really understand why but I find a solution !

I put this in scene:hide()  :

if(phase == "will") then moveMeteor3 = false

and on the gameOver scene i put this in the scene:create () ans not out the scene :

currentscoreTimer = composer.getVariable("score")

Thank you anyway for your help !  :wink:

Be Happy !  :slight_smile:

Bye !

Lucas

moveMeteor3 = nil basically forced Corona to no longer know about that function.

If you do this:

Runtime: addEventListener("enterFrame", harder)

you have to somewhere do:

Runtime: removeEventListener("enterFrame", harder)

Normally you would do that before you call composer.gotoScene() to go to the next scene or in scene:hide()'s “will” phase. Things like Runtime enterFrame listeners, physics, timers and transitions will still want to run when you leave your scene. It’s your responsibility to keep a handle (variable that keeps track of the object) to things you need to remove and then remove them at the appropriate time.

Rob

Rob meant:

Runtime: removeEventListener("enterFrame", harder)

Good catch Jon!