Extreme lag and occasional moments of speed-ups

In this video, pay close attention to the logs.

What does this instruction do? How do you move enemies?

moveEnemiesTimer = timer.performWithDelay(2, moveEnemies, -1) 

You don’t have to check (code below) both arguments obj1 and obj2 in removeOnPlayerHit. Just simply call removeOnPlayerHit(event.object1) or removeOnPlayerHit(event.object2)

if(obj1 ~= nil and obj1.id == "enemy") then   display.remove(obj1) end if(obj2 ~= nil and obj2.id == "enemy") then   display.remove(obj2) end

You can even rewrite removeOnPlayerHit function simpler like that

local function removeOnPlayerHit(obj)   if ( ( obj ~= nil ) and ( (obj.id == "enemy") or (obj.id == "enemy2") or (obj.id == "enemy3") or (obj.id == "enemy4") ) ) then     display.remove(obj)   end end

Solution find on http://stackoverflow.com/questions/22436782/corona-sdk-remove-all-objects-in-a-group

while middleGroup.numChildren \> 0 do   local child = middleGroup[1]   if child then child:removeSelf() end end

I notice on video in slow motion speed that about 7 sec on console you have twice times printed hidden and shown (hidden  hidden  shown shown in this order). This happens after you back from “try again” scene. Also on about 21 sec after you click “Try again” console print shown hidden and again shown. I think it is too many. I don’t why this happen. May be check code in “try again” scene.

what does word self refer to in endJump and touchScreen function? May be you mean character.x and character.y?

I have changed the self.x and self.y to character.x and character.y, also the move enemies timer calls the function moveEnemies(), and here is the code for try again scene:

local composer = require( "composer" ) local scene = composer.newScene() local widget = require "widget" widget.setTheme("widget\_theme\_ios7") -- ----------------------------------------------------------------------------------- -- Code outside of the scene event functions below will only be executed ONCE unless -- the scene is removed entirely (not recycled) via "composer.removeScene()" -- ----------------------------------------------------------------------------------- local background local button -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- local function resumeGame() composer.gotoScene("level1") end -- create() function scene:create( event ) local sceneGroup = self.view background = display.newRect(\_CX, \_CY, \_CW, \_CH) background:setFillColor(0) button = widget.newButton( { x = \_CX, y = \_CY, id = "button", label = "Try Again", onEvent = resumeGame } ) sceneGroup:insert(background) sceneGroup:insert(button) end -- show() function scene:show( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is still off screen (but is about to come on screen) elseif ( phase == "did" ) then -- Code here runs when the scene is entirely on screen end end -- hide() function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Code here runs when the scene is on screen (but is about to go off screen) elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen end end -- destroy() function scene:destroy( event ) local sceneGroup = self.view -- Code here runs prior to the removal of scene's view end -- ----------------------------------------------------------------------------------- -- Scene event function listeners -- ----------------------------------------------------------------------------------- scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) scene:addEventListener( "destroy", scene ) -- ----------------------------------------------------------------------------------- return scene

Try this (in try again scene)

local function resumeGame(event) if ( "ended" == event.phase ) then composer.gotoScene("level1") end end

It seems resumeGame function is call twice. One with argument event.phase == began and second time with argument event.phase == ended. 

Alternatively replace onEvent with onRelease when create button.

Read about it https://docs.coronalabs.com/api/library/widget/newButton.html 

I have tried the game 7 times, and no crashes, lag, or speed-ups have occurred, I hope its safe to say that the problem has been resolve, shown and hidden are printing normally now, instead of multiple times and no stuttering occurs when transitioning between try again and level1, thank you very much.

I’m glad I could help:) Good luck :slight_smile:

I apologize for showing the entire code, I do not need a complete rewrite, I just want  tips, suggestions, and/or code snippets.

IF any articles are found relating to this, feel free to send them.

When a problem occur? May be after touch screen? Consider use tap listener instead touch. 

function endJump() character:applyForce(0, 0, self.x, self.y) end

Does it do something useful? 

Edit :

May be you have too many objects in a game?

Are you sure that all event listerners are removed correctly after you removed level1 scene? I not sure that scene:hide metod is invoked. Can you check that?

When it is a tap listener, the player can not jump at all.

Also, Occasionally I get error saying: Attempt to call method applyForce (a nil value).

Does character spirite exist all the time?

Your physic engine is up ad working even level1 scene id off screen? Am I right?

This video shows all three of my current errors. 

One there is lots of lag, two, it goes really quick all of a sudden, and three, it crashes from an error.

https://www.youtube.com/watch?v=rpLGLAlP8Jc

I notice 

(line from playerHit method)

character:setLinearVelocity(0, nil)

but function setLinearVelocity require two numbers. Also changing position of object when physic engine is on is not good idea I think

(line from playerHit method). Why do you not pause physics engine after you leave scene level1? I think it is imporant.

character.x = \_L + 250

In playerHit method after call to gotoScene() I’m  not sure that  rest of code is executed. Check that.

The same thing occurs, it always seems to happen when you choose one character, die, then choose the other and start.

This is the code for the phase == “did”:

elseif ( phase == "did" ) then -- Code here runs immediately after the scene goes entirely off screen physics.pause() end

Try adding print statement in enterframe or collision functions…and when you leave the scene, see your simulator output if it is printing that statements which you have put in your enterframe or collision functions

Problem seems to be related with moving of character. Add print statement and observe console.

function endJump() print("applyForce in endJump") character:applyForce(0, 0, self.x, self.y) end function touchScreen(event) if (event.phase == "began") then if (vy \> -25 and vy \< 25) then print("applyForce in touchScreen") character:applyForce(0, -85, self.x, self.y) timer.performWithDelay(500, endJump, 1) end end end

Little improvments for your code

function spawnEnemies() numOfEnemy = math.random(1, 4) if numOfEnemy == 1 then enemy = display.newSprite(beetle, beetleSequenceData) enemy.x = \_R + 100 enemy.y = \_CY enemy.hasBeenScored = false physics.addBody(enemy, "dynamic", physicsData:get("beetle")) enemy.xScale = -1 enemy.id = "enemy" enemy.isFixedRotation = true enemy:play() group:insert(enemy) elseif numOfEnemy == 2 then enemy2 = display.newSprite(vulture, vultureSequenceData) enemy2.x = \_R + 100 enemy2.y = \_CY - (enemy2.height \* 0.25) enemy2.hasBeenScored = false physics.addBody(enemy2, "dynamic", physicsData:get("vulture")) enemy2.xScale = -1 enemy2.gravityScale = -0.01 enemy2.id = "enemy2" enemy2.isFixedRotation = true enemy2:play() specialGroup:insert(enemy2) elseif numOfEnemy == 3 then enemy3 = display.newSprite(scorpion, scorpionSequenceData) enemy3.x = \_R + 100 enemy3.y = \_CY enemy3.hasBeenScored = false physics.addBody(enemy3, "dynamic", physicsData:get("scorpion")) enemy3.xScale = -1 enemy3.id = "enemy3" enemy3.isFixedRotation = true enemy3:play() group:insert(enemy3) else enemy4 = display.newSprite(bee, beeSequenceData) enemy4.x = \_R + 100 enemy4.y = \_CY - (enemy4.height \* 0.25) enemy4.hasBeenScored = false physics.addBody(enemy4, "dynamic", physicsData:get("bee")) enemy4.xScale = -1 enemy4.gravityScale = -0.01 enemy4.id = "enemy4" enemy4.isFixedRotation = true enemy4:play() specialGroup:insert(enemy4) end end

Instead two call 

removeOnPlayerHit(event.object1, nil) removeOnPlayerHit(nil, event.object2)

you can write one

removeOnPlayerHit(event.object1, nil) removeOnPlayerHit(event.object2, nil)

and remove unneccessary if statements in onCollision function.

Why do you use timer to move enemies instead proper physics function? and how do you move character?

Some helpful article :slight_smile:

https://coronalabs.com/blog/2011/09/14/how-to-spawn-objects-the-right-way/

https://coronalabs.com/blog/2013/02/19/more-physics-tricks-explained/

Wow thank you for all this information I will try it and look into it.

The timer spawns the enemies, not move them, and which if statements are unnecessary?