Attempt to index field '?' a nil value error (a different one)

This is actually exactly what I did to generate each of my shapes, I did not use auto-trace, I drew the polygons myself, it was giving me problems before. Should I use coordinates with Corona’s physics body maker?

No, the physics editor shapes should work just fine.

Can you set the physics draw mode to hybrid and give us a screen shot if your objects that are colliding?

Is playerHit() your collision handling function?

Another function onCollision handles collision and uses playerHit(): 

function onCollision(event) local function removeOnPlayerHit(obj1, obj2) 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 local function showPlayerHit() local tmr\_onPlayerHit = timer.performWithDelay(1, playerHit, 1) end if event.phase == "began" then if((event.object1.id == "enemy" or event.object1.id == "enemy2" or event.object1.id == "enemy3" or event.object1.id == "enemy4") and event.object2.id == "character") then showPlayerHit() removeOnPlayerHit(event.object1, nil) elseif(event.object1.id == "character" and (event.object2.id == "enemy" or event.object2.id == "enemy2" or event.object2.id == "enemy3" or event.object2.id == "enemy4")) then showPlayerHit() removeOnPlayerHit(nil, event.object2) end end end

https://www.youtube.com/watch?v=s23FbFKniTY&feature=youtu.be

It looks like your enemies are still made up of multiple bodies instead of simple polygons. I’m not sure this is the cause. What I would suggest doing to verify what’s happening is put more print statements in your code.

For instance in your collision function print out the names of the two bodies that are colliding:

function onCollision(event)     print( "Object 1", event.object1.id, "Object 2", event.object2.id, event.phase )     ...

This will tell you the two objects that are colliding, more on that in a bit, but it will also tell you if the collision handler is being entered twice. Now you will get multiple prints since there are multiple phases, so you’re looking to see if you’re getting two “began”'s in a row.

I’ve not seen where you’re creating the object or adding the bodies. Are you by any chance adding the bodies in scene:show()? Can you post your scene:show() function if that’s the case?

All bodies are added in scene:create. There is a physics.pause in scene:hide, could that be the cause?

This is what was printed on the console on a collision:

Object 1 character Object 2 enemy3 began Object 1 character Object 2 enemy3 began Object 1 character Object 2 enemy3 began Object 1 character Object 2 enemy3 ended

On your scene that you go to when you run into an enemy… the one with the black screen and a blue button. Can you post the code for that scene?

Thanks

Rob

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(event) if ( "ended" == event.phase ) then composer.gotoScene("level1") end 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", onRelease = 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

_CX, _CY, _CW, and _CH are some globals I intend to remove.

Is it your intent that when they die and go to this scene that the level start over or resume? If you want it to start over then you should:

local function resumeGame(event) if ( "ended" == event.phase ) then composer.removeScene( "level1" ) --\<----- added this line composer.gotoScene("level1") end end

You are going back to level 1 in an in-between state. The main reason to have a cut scene like this is to give you a chance to remove the scene. This is the fastest/easiest way to reset a scene. If you wanted to do something more complex like move them back to a save point, not loose all their progress, not reset scores and such, then you have to take more effort to reset the scene yourself.

Rob

I want them to resume their progress just with one less life. Is there a “better” alternative to do this?

What is the purpose of the black screen? Do you have further plans for it?

In the sci-fi shooter I’m building in my spare time, when I take enough hits to die, I simply subtract one from my lives, hide a heart and let the game keep going. When my lives run out, then I jump to a game over scene.

I removed the black screen but the problem still occurs. 

It seems to happen when the player simultaneously hits two edges on an enemy.

Are you still getting the multiple “began” phases?

Yes.

Did these happen all at once or was one the began’s from earlier? If they came in together, I would have expected 3 lives to have been lost.  It’s more helpful to copy/paste the entire log conversation. In this case I could have looked at the time stamp and answered my own question.

Thanks

Rob

Hi @sdktester15,

Each body element in a multi-element body will generate a collision event. I thought that it was mentioned specifically in the Collisions guide, but it looks like I didn’t state it clearly enough (I’ll add a note for that).

For your case, you should probably set a property (flag) upon the first collision, and then ignore further collisions until you consider things “resolved”, i.e. the player dies, the enemy is removed, after a short amount of time like 100 milliseconds, etc.

Brent

They happened all at once.

Using a boolean variable right? But, how would I check for the first began phase?