Below is the usage of Global Collision:
local main = display.newImage( "mainRole.png", 160, 240 ) physics.addBody( main, { density = 1.0, friction = 0.3, bounce = 0.2 } ) main.myName = "mainRole" local fruit1 = display.newImage( "fruit.png", 100, 120 ) physics.addBody( fruit1, { density = 1.0, friction = 0.3, bounce = 0.2 } ) fruit1.myName = "fruit1" local fruit2 = display.newImage( "fruit.png", 300, 220 ) physics.addBody( fruit2, { density = 1.0, friction = 0.3, bounce = 0.2 } ) fruit2.myName = "fruit2" local function onGlobalCollision( event ) if ( event.phase == "began" ) then if((event.object1.myName=="mainRole" and event.object2.myName=="fruit1") or (event.object1.myName=="fruit1 and event.object2.myName=="mainRole")) then print( "began: " .. event.object1.myName .. " and " .. event.object2.myName ) if(fruit1 ~= nil) then print("Remove fruit1") fruit1:removeSelf( ) fruit1 = nil end elseif((event.object1.myName=="mainRole" and event.object2.myName=="fruit2") or (event.object1.myName=="fruit2" and event.object2.myName=="mainRole")) then print( "began: " .. event.object1.myName .. " and " .. event.object2.myName ) if(fruit2 ~= nil) then print("Remove fruit2") fruit2:removeSelf( ) fruit2 = nil end end elseif ( event.phase == "ended" ) then print( "ended: " .. event.object1.myName .. " and " .. event.object2.myName ) end end Runtime:addEventListener( "collision", onGlobalCollision )We add the specific name for each object.
When the collision happens, we can know which two objects collide with each other by verify the object names.
However, when we run the codes shown above, we may find that sometimes Runtime error will happen.
In executing fruit1:removeSelf( ), it will tell you that fruit1 is nil.
It is strange since we do check if(fruit1 ~= nil).
For fruit2, the problem is similar.
From the log message, the code print( "began: " .. event.object1.myName .. " and " .. event.object2.myName ) may run few times, and then execute print("Remove fruit1") after that.
It seems that this function is multi-entry.
A multi-entry function without critical section mechanism to protect it is liable to corrupt the data.
To solve this problem, we can make the removal of objects to other place, like the following codes:
local removeFruit1 = false local removeFruit2 = false local main = display.newImage( "mainRole.png", 160, 240 ) physics.addBody( main, { density = 1.0, friction = 0.3, bounce = 0.2 } ) main.myName = "mainRole" local fruit1 = display.newImage( "fruit.png", 100, 120 ) physics.addBody( fruit1, { density = 1.0, friction = 0.3, bounce = 0.2 } ) fruit1.myName = "fruit1" local fruit2 = display.newImage( "fruit.png", 300, 220 ) physics.addBody( fruit2, { density = 1.0, friction = 0.3, bounce = 0.2 } ) fruit2.myName = "fruit2" local function onGlobalCollision( event ) if ( event.phase == "began" ) then if((event.object1.myName=="mainRole" and event.object2.myName=="fruit1") or (event.object1.myName=="fruit1 and event.object2.myName=="mainRole")) then print( "began: " .. event.object1.myName .. " and " .. event.object2.myName ) removeFruit1 = true elseif((event.object1.myName=="mainRole" and event.object2.myName=="fruit2") or (event.object1.myName=="fruit2" and event.object2.myName=="mainRole")) then print( "began: " .. event.object1.myName .. " and " .. event.object2.myName ) removeFruit2 = true end elseif ( event.phase == "ended" ) then print( "ended: " .. event.object1.myName .. " and " .. event.object2.myName ) end end Runtime:addEventListener( "collision", onGlobalCollision ) local function removeAction() if(removeFruit1) then if(fruit1 ~= nil) then print("Remove fruit1") fruit1:removeSelf( ) fruit1 = nil removeFruit1 = false end end if(removeFruit2) then if(fruit2 ~= nil) then print("Remove fruit2") fruit2:removeSelf( ) fruit2 = nil removeFruit2 = false end end end timer.performWithDelay( 50, removeAction,-1 )
沒有留言:
張貼留言