问题
Follow up of this question, Storyboard with Ceramic Tile Engine, and with Collision Detection is still a mystery. Here is the code:
-- hide status bar
display.setStatusBar(display.HiddenStatusBar)
local storyboard = require("storyboard")
--Set up the physics world
local physics = require("physics")
physics.start()
physics.setGravity(0, 0)
physics.setDrawMode('hybrid')
local scene = storyboard.newScene()
local widget = require("widget")
-- Add Hero to Physics
local hero = display.newImage("images/man.png")
hero.x = 40
hero.y = 80
local heroCollisionFilter = { categoryBits = 4, maskBits = 2 }
local heroBody = { filter=heroCollisionFilter, isSensor=true }
physics.addBody(hero, "dynamic", heroBody)
function scene:createScene( event )
local group = self.view
local ceramic = require("Ceramic")
ceramic.showPrints = false
local map = ceramic.buildMap("maps/map.lua")
-- collisionLayer = map.layer['Collision']
-- collisionLayer.ccName = "map"
-- physics.addBody(collisionLayer, "static", { friction=0.5, bounce=0.3 } )
map.y = 0
map.setCameraDamping(10)
map.layer['World']:insert(hero)
end
function onGlobalCollision(event)
if(event.phase == "began") then
print( "Global report: " .. event.object1.ccName .. " & " .. event.object2.ccName .. " collision began" )
elseif(event.phase == "ended") then
print( "Global report: " .. event.object1.ccName .. " & " .. event.object2.ccName .. " collision ended" )
end
print( "**** " .. event.element1 .. " -- " .. event.element2 )
end
Runtime:addEventListener("collision", onGlobalCollision)
scene:addEventListener( "createScene", scene )
return scene
And the screenshot looks like:
However, collision never triggers, as the print
message does not appear in Terminal at all.
I'm using:
- Corona SDK
- Ceramic Tile Engine
- Corona module: storyboard, physics
How can I enable Collision Detection ? Are the parameters correct ?
Edit 2013/10/27
The Tiled map settings are as follow:
When running in Mac OS X, the collision does not happen ( only the hybrid layer changes color ).
When running in Windows 7, the code crashes on this line:
ceramic.buildMap("maps/map.lua")
with error:
attempt to call global 'reversePolygon' (a nil value) in Ceramic.lua: 617
After I comment out the following lines, the error is gone:
collisionLayer = map.layer['Collision']
collisionLayer.ccName = "map"
physics.addBody(collisionLayer, "static", { friction=0.5, bounce=0.3 } )
but the collision function does not get called.
回答1:
Box2D collision detection is specified through the properties of a layer, tile, or object in an object layer. Ceramic adds physics automatically if the physics:enabled
property is set to true
.
Physics parameters are also set within properties. This:
physics.addBody(myObject, {friction = 0.5, bounce = 0.1})
Would correspond, in Tiled's properties, to this:
physics:friction = 0.5
physics:bounce = 0.1
回答2:
For future people who are stuck in Collision Detection in Corona SDK with Tiled and Ceramic Tile Engine
In further testing, I found out that the issue of collision event not firing is I used a wrong set of collision events. The working collision events are :
local function onLocalCollision(self, event)
print("collision")
if event.phase == "began" then
print("Collision began")
elseif event.phase == "ended" then
print("Collision ended")
end
end
function onGlobalCollision(event)
if(event.phase == "began") then
print( "Global report: " .. event.object1.ccName .. " & " .. event.object2.ccName .. " collision began" )
elseif(event.phase == "ended") then
print( "Global report: " .. event.object1.ccName .. " & " .. event.object2.ccName .. " collision ended" )
end
print( "**** " .. event.element1 .. " -- " .. event.element2 )
end
function onPostCollision(event)
print("postCollision")
end
-- Local Collision
hero.collision = onLocalCollision
hero:addEventListener("collision", hero)
-- Global Collision
Runtime:addEventListener("collision", onGlobalCollision)
Runtime:addEventListener("postCollision", onPostCollision)
and each collision object has to have a name ( the property name ccName
, you can pick any name you want , but it has to be set in Tiled's object list ).
Also, I removed the categoryBits
and maskBits
, seems they make the collision detection invalid.
Points to note:
- Collision layer does not have to add to scene by programming ( it will be added automatically )
- Only 1 set of collision detection methods ( Local / Global ) is needed ( but 2 sets can be run in parallel )
- Turn off hybrid display mode when not needed, for better performance
- It doesn't matter what the Layer format is ( Base64 / CSV works fine )
- Remember to add
physics:enabled
in Collision Layer properties (physics:friction
andphysics:bounce
are optional , as per @CalebP's comment )
来源:https://stackoverflow.com/questions/19511038/collision-detection-with-ceramic-tile-engine-box-2d