以下是利用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 )
我們替每個物體都加上了專屬的名稱,在碰撞發生時,就可以利用名稱來分辨是那二個物體,
不過,以上的程式執行時,有時會遇到Runtime error,
執行fruit1:removeSelf( )時,它會告訴你fruit1是nil,
怪了,我們明明有檢查if(fruit1 ~= nil),
fruit2一樣有類似的情形,
從log來看,有時print( "began: " .. event.object1.myName .. " and " .. event.object2.myName )會執行好幾次,然後才執行print("Remove fruit1"),
看來,這個function是multi-entry,
multi-entry但又缺少critical section的保護機制,然免會出問題,
要解決這個問題,就是把remove的動作移到其它地方去,如下面用法:
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 )
沒有留言:
張貼留言