物理引擎
前言
在游戏中模拟真实的物理世界是比较麻烦的,通常都会交给物理引擎来做,比较知名的物理引擎有Box2D和Chipmunk。
在Cocos2d-x 2.x中,游戏直接使用物理引擎,引擎提供一个简单的CCPhysicsSprite,处理了物理引擎的body与CCSprite的关系,而物理引擎的其他元素并没有和引擎对应起来,游戏需要选择直接调用Box2D或Chipmunk的API来处理逻辑。然而直接使用物理引擎是比较复杂的,物理引擎的接口参数繁多、复杂、需要开发人员对物理引擎和Coco2d-x都很了解,才能把两者融合得很好。
这种情况在Cocos2d-x 3.x中有了改变,全新的Physics Integration,把Chipmunk和Box2D封装到引擎内部,开发者不必关心底层具体用的是哪个物理引擎,也不用直接调用物理引擎的接口。
Cocos2d-x 3.x默认使用Chipmunk作为内部物理引擎。
Physics Integration 做了以下深度融合:
(1)物理世界被融入到Scene中,即当创建一个场景时,可以指定这个场景是否使用物理引擎。
(2)Node自带body属性,也就是Sprite自带body属性。
(3)对物理引擎的Body(cc.PhysicsBody),Shape(cc.PhysicsShape),Contact(cc.PhysicsContact),Joint(cc.PhysicsJoint),World(cc.PhysicsWold)进行封装抽象,使用更加简单。
(4)更简单的碰撞检测监听:EventListenerPhysicsContact.
创建带物理世界的scene
使用下面方法创建带物理世界的scene:
local MainScene = class ("MainScene",function()
return display.newScene("MainScene",{
physics = 2})
end)
创建后,self:getPhysicsWorld()
用来获取场景绑定的物理世界对象。
PhysicsWorld()
默认是带重力的,大小为Vect(0.0f,-98.0f),也可以通过setGravity()
方法来改变重力值,如下:
self:getPhysicsWorld():setGravity(cc.p(0,-100))
在调试物理世界中物体运动模拟时,可以使用PyhsicsWorld
的setDebugDrawMask()
来开启调试模式。它能把物理世界中不可见的shape, joint和contact都可视化。当调试结束需要发布游戏的时候,需要把该debug
开关关闭
关闭DEBUG,传入参数cc.PhysicsWorld.DEBUGDRAW_NONE
。
创建物理边界
在物理世界中,所以物体均受重力的影响。物理引擎提供StaticShape创建一个不受重力影响的形状,在Cocos2d-x 2.x中,我们需要了解物理引擎的StaticShape相关的各种参数来完成边界设置。而在Cocos2d-x 3.x中,由cc.PhysicsBody
创建边界,然后由Node
添加到场景,addChild
内部自动碗好吃呢个边界添加到物理世界,Node
在这里起中介作用。
代码如下:
local size = display.size
local body = cc.PhysicsBody:createEdgeBox(size,cc.PHYSICSBODY_MATERIAL_DEFAULT,2)
local edgeNode = display.newNode()
edgeNode:setPosition(size.width/2,size.height/2)
edgeNode:setPhysicsBody(body)
self:addChild(edgeNode)
cc.PhysicsBody
包含很多工程方法,createEdgeBox
创建一个不受重力影响的矩形边界,参数含义依次是:
(1)矩形区域大小,这里设置为屏幕大小。
(2)设置材质,可选参数,默认为PHYSICSBODY_ MATERIAL DEFAULT
。
(3)边线宽度,可选参数,默认为1
。
然后我们创建一个Node,把刚刚创建的body附加到Node上,并设置好Node的position为屏幕中心点。最后把Node添加到scene。
Node的addChild方法,在Cocos2d-x 3. x中有对物理body做处理,它会自动把Node的body设置到scene的PhysicsWorld上去。
PhysicsBody中的工程方法,针对参数设置的body大小,会自动创建对应的PhysicsBody和一个PhysicsShape, 这也是通常情况下,直接使用物理引擎创建一个body需要做的事情。Cocos2d-x 3. x的Physics Integration 极大地简化了使用物理引擎的代码量。
创建受重力作用的sprite
在Cocos2d-x 3.0中创建一个受重力作用的Sprite也很简单。首先来看代码:
local oneSprite = display.newSprite("game/basketball/image/basketball.png")
-- local oneBody = cc.PhysicsBody:createBox(oneSprite:getContentSize(),cc.PHYSICSBODY_MATERIAL_DEFAULT,cc.p(