BUG: Greater than 0 if statement crash.

Ntero: Yeah, maybe, I’ll test with an event.phase == “ended” and see if that fixes it… [import]uid: 144504 topic_id: 33332 reply_id: 132458[/import]

UPDATE: So I was looking at the code, and I think I found out what was going wrong. First I commented out the Game Over if statement, Corona didn’t crash then. After that I recalled that you can’t have two storyboard overlays showing at the same time. So now I think I know what the problem was… With the regular scene.lives >= 0, it allowed the value to go down to -1, as with scene.lives > 0, only let the value go down to 0. When another object1 hits the sensor, the listener is run again, and the Game Over code if statement is checked again. It will register as a true if scene.lives == 0, but false if scene.lives actually is -1, so it would never run twice with the >= 0 if statement that subtracts the value, but for sure twice with the > 0 if statement that subtracts the value. Here is what I mean. (Look at the comments)

function gameObjects.sensor.listener( event )  
 if event.phase == "ended" and event.other.name == "object1" then  
 event.other:removeSelf()  
 print( event.other.name..": destroyed" )  
 if scene.debug == false and scene.lives \> 0 then -- Here is scene.lives \> 0.   
 scene.hudLives.objects[scene.lives]:removeSelf()  
 scene.lives = scene.lives - 1 -- Subtracts 1 from lives. When scene.lives \>= 0 this will subtract even when the value is 0, but with \> 0 it will stop at 0  
 print( scene.lives )  
 end  
 if scene.lives == 0 then -- If the subtraction ends at 0, and this function is   
-- triggered again, this will trigger every time calling showOverlay, which is  
-- probably the cause of the crashes.  
 -- If lives are no more, then do game over sequence.  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
 end  
 end  
end  

To fix this I remembered a string variable that I use for my pause mechanism, called gameState. Now the Game Over code looks like this.

if scene.lives == 0 and scene.gameState ~= "over" then  
 -- If lives are no more, then do game over sequence.  
 scene.gameState = "over"  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
end  

Now if gameState does not equal “over” then it will trigger, but change gameState to “over” when it does, insuring only running once… Works perfectly now :smiley: Hope this all makes sense… lol

Thanks!!!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132598[/import]

And here is the debug code:

A table: 0x109d839f0 3 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 2 A table: 0x109d839f0 2 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 1 A table: 0x109d839f0 1 B - scene.hudLives found C - scene.hudLives.objects found D - scene.hudLives.objects[scene.lives] found table E - theObj is a valid display object F - scene.hudLives found G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 A table: 0x109d839f0 0 G table: 0x109d839f0 0 [import]uid: 144504 topic_id: 33332 reply_id: 132459[/import]

From the Corona Docs (Gotchas on the collision event):
http://docs.coronalabs.com/api/event/collision/index.html
[text]
Restrictions on Modifying Objects
The objects involved in the collision should not be removed or any of it’s properties altered during a collision event. You should use timer.performWithDelay() if they want to modify object position values or other properties within the collision events.

Removing the object or modifying the properties in the collision event could cause the simulator to crash.
[/text]

Even if it’s not a collision object, you should be reluctant about removing anything inside of collision events. using performWithDelay, with a timer of 1, allows you to designate a ‘next frame’ operation.

Also, that event.other:removeSelf is definitely going to cause you major issues. [import]uid: 134101 topic_id: 33332 reply_id: 132460[/import]

(Edit: Looks like Ntero and I were posting at the same time there. Rather I was typing while Ntero was pressing submit.)

@jake72,

  1. Is the scene variable a reference to a table {} or is it a reference to a display group? It looks like a plain table.

  2. Is line 39 of the dump the end and then the game crashed? i.e. Did it just keep printing A, G messages over and over or did it completely crash.

  3. Ntero is likely on to something. If you’re deleting a physics object in the middle of processing you could get into trouble. (Sorry I misread that dump. I don’t look at them all that often and didn’t even notice the fact that the functions were signed org.Box2D.Box2D …)

You might try a deferred removal to see if that helps:
[lua]timer.performWithDelay( 10, function() scene.hudLives.objects[scene.lives]:removeSelf() end )[/lua]

This should keep the removal from occurring till after you get out of the box2D processing code as well as your current handler.

-Ed

[import]uid: 110228 topic_id: 33332 reply_id: 132461[/import]

  1. It is created with the storyboard.newScene() functions…

  2. A timer spawns multipule object1s, until lives = 0 and it is canceled, and then after thet go off screen, and the “sensor” object thats a isSensor physics object detects a collision and runs the lister function. It is fine with everything until it hits 0, and another object hits the sensor, where it crashes…

  3. Yes, I think it may have something to do with that but it has no problem until the lives hit 0 and another object comes over the sensor…

Thanks!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132518[/import]

UPDATE: So I was looking at the code, and I think I found out what was going wrong. First I commented out the Game Over if statement, Corona didn’t crash then. After that I recalled that you can’t have two storyboard overlays showing at the same time. So now I think I know what the problem was… With the regular scene.lives >= 0, it allowed the value to go down to -1, as with scene.lives > 0, only let the value go down to 0. When another object1 hits the sensor, the listener is run again, and the Game Over code if statement is checked again. It will register as a true if scene.lives == 0, but false if scene.lives actually is -1, so it would never run twice with the >= 0 if statement that subtracts the value, but for sure twice with the > 0 if statement that subtracts the value. Here is what I mean. (Look at the comments)

function gameObjects.sensor.listener( event )  
 if event.phase == "ended" and event.other.name == "object1" then  
 event.other:removeSelf()  
 print( event.other.name..": destroyed" )  
 if scene.debug == false and scene.lives \> 0 then -- Here is scene.lives \> 0.   
 scene.hudLives.objects[scene.lives]:removeSelf()  
 scene.lives = scene.lives - 1 -- Subtracts 1 from lives. When scene.lives \>= 0 this will subtract even when the value is 0, but with \> 0 it will stop at 0  
 print( scene.lives )  
 end  
 if scene.lives == 0 then -- If the subtraction ends at 0, and this function is   
-- triggered again, this will trigger every time calling showOverlay, which is  
-- probably the cause of the crashes.  
 -- If lives are no more, then do game over sequence.  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
 end  
 end  
end  

To fix this I remembered a string variable that I use for my pause mechanism, called gameState. Now the Game Over code looks like this.

if scene.lives == 0 and scene.gameState ~= "over" then  
 -- If lives are no more, then do game over sequence.  
 scene.gameState = "over"  
 storyboard.showOverlay( "gameOver", { isModal = true } )  
 timer.cancel( scene.timers.spawn )  
 print( "\n\n GAME OVER \n\n" )  
  
end  

Now if gameState does not equal “over” then it will trigger, but change gameState to “over” when it does, insuring only running once… Works perfectly now :smiley: Hope this all makes sense… lol

Thanks!!!

-Jake [import]uid: 144504 topic_id: 33332 reply_id: 132598[/import]