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 )
沒有留言:
張貼留言