由于物理世界的模拟涉及很多函数,所以单独写一篇来记录了。
1.创建物理世界
打勾就可以了,不然碰撞检测会没反应。参考了论坛的才发现要打勾
http://forum.cocoseditor.com/forum.php?mod=viewthread&tid=18&extra=page%3D1
2.物理刚体与形状
cocos2d提供很多形状,有标准的box,circle,也有自定义的多边形Polygon,还有相框的,段式的,链式的。这些都有共通性,都是调用create()和init(),需要用到的时候再看API行了。
关键是怎么创建,怎么和Sprite或者Node联系起来,并设置碰撞回调函数。
基本步骤
1.定义刚体PhysicsBody.并添加到PhysicsWorld
2.定义形状PhysicsShape。
3.把形状赋值给刚体(刚体是实物,形状是虚物,实际碰撞检测用刚体实现,形状负责实现渲染功能)
4.最后才把Body和Shape赋值给Sprite或者Node。
官网提供的代码中,通过一个cce文件实现以上所有步骤。
2.1简单的图形
几何shape如下设计:Sprite->PhysicsBody->PolygonShape
<?xml version="1.0" encoding="UTF-8"?> <Sprite designWidth="320" designHeight="480" positionX="0.5" positionY="0.5" texture="img/shipgold.plist/huangjin1.png"> <PhysicsBody dynamic="true" mass="10"> <PolygonShape> <Vertex x="-1" y="-14"/> <Vertex x="-13" y="-13"/> <Vertex x="-2" y="13"/> <Vertex x="16" y="10"/> <Vertex x="20" y="2"/> <Vertex x="19" y="-12"/> </PolygonShape> <PolygonShape> <Vertex x="-21" y="-1"/> <Vertex x="-16" y="8"/> <Vertex x="-2" y="13"/> <Vertex x="-13" y="-13"/> <Vertex x="-20" y="-9"/> </PolygonShape> </PhysicsBody> </Sprite>
2.2 复杂图形
如车子设计,会把Body关联到Layer,而不是单个Sprite如下
flappyBird中两根柱子的设计<?xml version="1.0" encoding="UTF-8"?> <Layer designWidth="720" designHeight="1280" width="720" height="1280" positionX="360" positionY="640"> <Sprite designWidth="720" designHeight="1280" positionX="0.5" positionY="0.5" tag="100" texture="img/shipgold.plist/cheshen.png"> </Sprite> <Sprite positionX="0" positionY="0" tag="2005" visible="true" texture="img/shipgold.plist/chezhuanpan.png"> </Sprite> <Sprite texture="img/shipgold.plist/chegulu.png" positionX="35" positionY="-50" scaleX="0.8" scaleY="0.8" tag="2002" visible="true"/> <Sprite texture="img/shipgold.plist/chegulu.png" tag="2001" positionX="-25" scaleX="0.8" scaleY="0.8" visible="true" positionY="-50"/> <PhysicsBody dynamic="false" gravityEnable="false" rotationEnabled="true"> <EdgeSegmentShape fromX="-70" fromY="20" toX="70" toY="20" border="1"/> </PhysicsBody> <Component name="com.makeapp.game.shipgold.ControllerTurn"/> </Layer>
发现上面那样直接添加PhysicsBody会影响Sprite的位置。导致位置错误,通过比较,发现是anchorPoint不一样导致的,Sprite中我设置为(0,0),PhysicsBody中,没有anchorPoint的设置,默认是(0.5,0.5)。所以Sprite的锚点也要根据(0.5,0.5)设置。怪不得Demo中的width和position都是随便定义的。<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?> <Sprite designWidth="720" designHeight="1280" sizeType="Percent" width="1" height="1" anchorPointX="0" anchorPointY="0" name="pipeBar" zorder="0"> <!--Pipe高度为800,而上pipe刚好初始位置是800,如果下面pipe初始Y位置为0, 上下管道没空间,因此,设置下面的pipe的初始Y位置为-300,这样上下pipe刚好给出空间300。--> <Sprite texture="textures/flappy_packer.plist/holdback1.png" positionX="0" positionY="30" anchorPointY="0" anchorPointX="0" sizeType="Percent" zorder="0" width="1" height="1" designWidth="146" designHeight="830" name="downPipe"> <PhysicsBody dynamic="false" mass="10" collisionBitmask="1" contactTestBitmask="2"> <BoxShape width="146" height="820" offsetX="73" offsetY="410"/> </PhysicsBody> </Sprite> <Sprite texture="textures/flappy_packer.plist/holdback2.png" positionX="0" positionY="1150" anchorPointX="0" anchorPointY="0" sizeType="Percent" width="1" height="1" designWidth="146" designHeight="830" name="upPipe" zorder="0"> <PhysicsBody dynamic="false" mass="10" collisionBitmask="1" contactTestBitmask="2"> <BoxShape width="146" height="820" offsetX="73" offsetY="410"/> </PhysicsBody> </Sprite> </Sprite></span>
因此,我根据图片的大小,调整了锚点和位置偏移,使得效果和之前一样,但是又能适应物理控件,如下:
这里有个疑问:shape的大小参考什么定义?<?xml version="1.0" encoding="UTF-8"?> <Sprite designWidth="146" designHeight="1280" sizeType="Percent" width="1" height="1" anchorPointX="0" anchorPointY="0" name="pipeBar" zorder="0" positionX="0" positionY="0"> <!--Pipe高度为800,而上pipe刚好初始位置是800,如果下面pipe初始Y位置为0, 上下管道没空间,因此,设置下面的pipe的初始Y位置为-300,这样上下pipe刚好给出空间300。--> <Sprite texture="textures/flappy_packer.plist/holdback1.png" positionX="73" positionY="440" anchorPointY="0.5" anchorPointX="0.5" sizeType="Percent" zorder="0" width="1" height="1" designWidth="146" designHeight="830" name="downPipe"> </Sprite> <Sprite texture="textures/flappy_packer.plist/holdback2.png" positionX="73" positionY="1560" anchorPointX="0.5" anchorPointY="0.5" sizeType="Percent" width="1" height="1" designWidth="146" designHeight="830" name="upPipe" zorder="0"> </Sprite> </Sprite>
如下图,红色的点就是shape的中心,所以shape的中心是对准Sprite的中心的,它就是坐标原点。如2.1的例子,有负数。
如果是长方形的,就不需要设置Vertext,只需要设置Box的长宽了。所以上面的代码改进如下,只是加了长宽定义。
<?xml version="1.0" encoding="UTF-8"?> <Sprite designWidth="146" designHeight="1280" sizeType="Percent" width="1" height="1" anchorPointX="0" anchorPointY="0" name="pipeBar" zorder="0" positionX="0" positionY="0"> <!--Pipe高度为800,而上pipe刚好初始位置是800,如果下面pipe初始Y位置为0, 上下管道没空间,因此,设置下面的pipe的初始Y位置为-300,这样上下pipe刚好给出空间300。--> <Sprite texture="textures/flappy_packer.plist/holdback1.png" positionX="73" positionY="440" anchorPointY="0.5" anchorPointX="0.5" sizeType="Percent" zorder="0" width="1" height="1" designWidth="146" designHeight="830" name="downPipe"> <PhysicsBody dynamic="false" mass="10" collisionBitmask="1" contactTestBitmask="2"> <BoxShape width="146" height="820" offsetX="0" offsetY="0"/> </PhysicsBody> </Sprite> <Sprite texture="textures/flappy_packer.plist/holdback2.png" positionX="73" positionY="1560" anchorPointX="0.5" anchorPointY="0.5" sizeType="Percent" width="1" height="1" designWidth="146" designHeight="830" name="upPipe" zorder="0"> <PhysicsBody dynamic="false" mass="10" collisionBitmask="1" contactTestBitmask="2"> <BoxShape width="146" height="820" offsetX="0" offsetY="0"/> </PhysicsBody> </Sprite> </Sprite>
刚体会被穿透
http://blog.csdn.net/xzongyuan/article/details/40160441
调整刚体的速度
http://blog.csdn.net/xzongyuan/article/details/40025247