cocos2d-x 内置物理引擎探索

Cocos2d-x采用了Box2D物理引擎和Chipmunk物理引擎来模拟真实的物理世界。Box2D几乎能模拟所有的物理效果,而chipmunk则是个更轻量的引擎等。而在Cocos2d-x3.2版本中认采用Chipmunk,所以我就以Chip-munk来讲解。并且为了简化物理引擎和Cocos2d-x的交接,Cocos2d-x直接提供函数来设置物体参数,不需要我们采用Chip-munk原生的函数来设置,这大大简化的代码的编写。
Chipmunk是采用C语言编写的2D刚体物理仿真库,包含4种基本的对象类型,分别是:
空间:空间是Chipmunk中模拟对象的容器。你将刚体、形状、关节添加进入一个空间,然后将空间作为一个整体进行更新。空间控制着所有的刚体、形状和约束之间的相互作用。
刚体:一个刚体容纳着一个对象的物理属性(如质量、位置、角度、速度等)。认情况下,它并不具有任何形状,直到你为它添加一个或者多个碰撞形状进去。如果你以前做过物理粒子,你会发现它们的不同之处是刚体可以旋转。在游戏中,通常刚体都是和一个精灵一一对应关联的。你应该构建你的游戏以便可以使用刚体的位置和角度来绘制你的精灵。
碰撞形状:因为形状与刚体相关联,所以你可以为一个刚体定义形状。为了定义一个复杂的形状,你可以给刚体绑定足够多的形状。形状包含着一个对象的表面属性如摩擦力、弹性等。
约束/关节:约束和关节被用来描述刚体之间是如何关联的
人们经常对Chipmunk中的刚体和碰撞形状以及两者与精灵之间的关系产生混淆。精灵是对象的可视化表现,而碰撞形状是定义对象应该如何碰撞的不可见的属性。精灵和碰撞形状两者的位置和角度都是由刚体的运动控制的。通常你应该创建一个游戏对象类型,把这些东西捆绑在一起。
在Cocos2d-x3.2中,物理世界被融入到Scene中,即当创建一个场景时,就可以指定这个场景是否使用物理引擎。

sprite自带body属性,直接设置body,而形状、约束等属性添加到body中即可。碰撞的检测通过事件分发器来监控,所以你首先要创建监听器--EventListenerPhysicsContact,再把其添加到分发器中。


  1. #include"HelloWorldScene.h"
  2. USING_NS_CC;
  3. //物理引擎标识
  4. intball1Mask=1<<0;//球1
  5. intball2Mask=1<<1;//球2
  6. intwallMask=1<<2;//地面
  7. Scene*HelloWorld::createScene()
  8. {
  9. //创建有物理空间的场景
  10. Scene*scene=Scene::createWithPhysics();
  11. //设置Debug模式,你会看到物体的表面被线条包围,主要为了在调试中更容易地观察
  12. scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
  13. HelloWorld*layer=HelloWorld::create();
  14. //把空间保持我们创建的层中,就是上面所说m_world的作用,方便后面设置空间的参数
  15. layer->setPhyWorld(scene->getPhysicsWorld());
  16. scene->addChild(layer);
  17. returnscene;
  18. }
  19. //on"init"youneedtoinitializeyourinstance
  20. voidHelloWorld::onEnter()
  21. {
  22. Layer::onEnter();
  23. //添加监听器
  24. autocontactListener=EventListenerPhysicsContact::create();
  25. //设置监听器的碰撞开始函数
  26. contactListener->onContactBegin=CC_CALLBACK_1(HelloWorld::onContactBegin,this);
  27. //添加到事件分发器中
  28. _eventdispatcher->addEventListenerWithSceneGraPHPriority(contactListener,this);
  29. }
  30. boolHelloWorld::init()
  31. {
  32. //////////////////////////////
  33. //1.superinitfirst
  34. if(!Layer::init())
  35. {
  36. returnfalse;
  37. }
  38. SizevisibleSize=Director::getInstance()->getVisibleSize();
  39. Pointorigin=Director::getInstance()->getVisibleOrigin();
  40. ballOne=Sprite::create();
  41. ballOne->setContentSize(Size(50,50));
  42. ballOne->setPosition(visibleSize.width/2,visibleSize.height/2);
  43. //创建物体,并且物体的形状为圆形,第一参数为半径,第二个参数为物体材质
  44. //第三个参数为边的厚度,就是在Debug模式下看到的物体外面线条的厚度,认为0
  45. PhysicsBody*ballBodyOne=PhysicsBody::createCircle(ballOne->getContentSize().width/2,PHYSICSBODY_MATERIAL_DEFAULT,Vec2(1,1));
  46. //
  47. //ballBodyOne->setCategoryBitmask(1);
  48. //是否设置物体为静态
  49. //ballBody->setDynamic(false);
  50. //设置物体的恢复力
  51. ballBodyOne->getShape(0)->setRestitution(1.0f);
  52. //设置物体的摩擦力
  53. ballBodyOne->getShape(0)->setFriction(0.0f);
  54. //设置物体密度
  55. ballBodyOne->getShape(0)->setDensity(1.0f);
  56. //设置质量
  57. //ballBodyOne->getShape(0)->setMass(5000);
  58. //设置物体是否受重力系数影响
  59. ballBodyOne->setGravityEnable(false);
  60. //设置物体的冲力
  61. Vectforce=Vect(500000.0f,500000.0f);
  62. ballBodyOne->applyImpulse(force);
  63. //把物体添加到精灵中
  64. ballOne->setPhysicsBody(ballBodyOne);
  65. //设置标志
  66. ballOne->setTag(1);
  67. this->addChild(ballOne);
  68. //设置第二个球
  69. ballTwo=Sprite::create();
  70. ballTwo->setContentSize(Size(100,100));
  71. ballTwo->setPosition(visibleSize.width/3,visibleSize.height/3);
  72. PhysicsBody*ballBodyTwo=PhysicsBody::createCircle(ballOne->getContentSize().width/2,PHYSICSBODY_MATERIAL_DEFAULT);
  73. //是否设置物体为静态
  74. //ballBodyTwo->setDynamic(false);
  75. ballBodyTwo->getShape(0)->setRestitution(1.0f);
  76. ballBodyTwo->getShape(0)->setFriction(0.0f);
  77. ballBodyTwo->getShape(0)->setDensity(1.0f);
  78. ballBodyTwo->setGravityEnable(false);
  79. force=Vect(-500000.0f,-500000.0f);
  80. ballBodyTwo->applyImpulse(force);
  81. ballTwo->setPhysicsBody(ballBodyTwo);
  82. ballTwo->setTag(2);
  83. this->addChild(ballTwo);
  84. //创建一个盒子,用来碰撞
  85. Sprite*edgeSpace=Sprite::create();
  86. PhysicsBody*boundBody=PhysicsBody::createEdgeBox(visibleSize,3);
  87. boundBody->getShape(0)->setFriction(0.0f);
  88. boundBody->getShape(0)->setRestitution(1.0f);
  89. edgeSpace->setPhysicsBody(boundBody);
  90. edgeSpace->setPosition(Point(visibleSize.width/2,visibleSize.height/2));
  91. this->addChild(edgeSpace);
  92. edgeSpace->setTag(0);
  93. ballBodyOne->setCategoryBitmask(ball1Mask);
  94. ballBodyOne->setCollisionBitmask(wallMask|ball1Mask|ball2Mask);
  95. ballBodyOne->setContactTestBitmask(wallMask|ball1Mask|ball2Mask);
  96. ballBodyTwo->setCategoryBitmask(ball2Mask);
  97. ballBodyTwo->setCollisionBitmask(wallMask|ball1Mask|ball2Mask);
  98. ballBodyTwo->setContactTestBitmask(wallMask|ball1Mask|ball2Mask);
  99. boundBody->setCategoryBitmask(wallMask);
  100. boundBody->setCollisionBitmask(wallMask|ball1Mask|ball2Mask);
  101. boundBody->setContactTestBitmask(wallMask|ball1Mask|ball2Mask);
  102. returntrue;
  103. }
  104. boolHelloWorld::onContactBegin(constPhysicsContact&contact)
  105. {
  106. if((contact.getShapeA()->getBody()->getCategoryBitmask()&ball1Mask)==ball1Mask){
  107. cclOG("ball1touchsomething");
  108. }
  109. if((contact.getShapeB()->getBody()->getCategoryBitmask()&ball1Mask)==ball1Mask){
  110. cclOG("ball1touchsomething");
  111. }
  112. if((contact.getShapeA()->getBody()->getCategoryBitmask()&ball2Mask)==ball2Mask){
  113. cclOG("ball2touchsomething");
  114. }
  115. if((contact.getShapeB()->getBody()->getCategoryBitmask()&ball2Mask)==ball2Mask){
  116. cclOG("ball2touchsomething");
  117. }
  118. returntrue;
  119. }
  120. voidHelloWorld::menuCloseCallback(Ref*pSender)
  121. {
  122. #if(CC_TARGET_PLATFORM==CC_PLATFORM_WP8)||(CC_TARGET_PLATFORM==CC_PLATFORM_WINRT)
  123. MessageBox("Youpressedtheclosebutton.WindowsstoreAppsdonotimplementaclosebutton.","Alert");
  124. return;
  125. #endif
  126. Director::getInstance()->end();
  127. #if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
  128. exit(0);
  129. #endif
  130. }
Cocos2d-x3.2封装了Chipmunk的碰撞过滤,方式与Chipmunk原生代码不同。Cocos2d-x3.2有三个碰撞过滤标志categoryBitmask、contactTestBitmask和collisionBitmask。这三个标志在目录...\cocos2d\cocos\physics\CCPhysicsShape.h下有英文的注释,下面是我的翻译和加上我的一些理解。
categoryBitmask:
分类掩码,定义了物体属于哪个分类。场景中的每个物理刚体可以被赋值一个多达32位的值(因为categoryBitmask为int型),每个对应32位掩码中的每一位,你在你的游戏中定义掩码值。结合collisionBitMask和contactTestBitMask属性, 你可以定义哪些物理刚体相互作用并且你的游戏何时接受这些相互作用的通知认值为0xFFFFFFFF(所有位都被设置)。
contactTestBitmask:
接触测试掩码,定义哪些刚体分类可以与本刚体产生相互作用的通知。当两个刚体在同一个空间,即物理世界中,每个刚体的分类掩码会和其他刚体的接触测试掩码进行逻辑与的运算。如果任意一个比较结果为非零值,产生一个PhysicsContact对象并且传递到物理世界协议中,这里协议指我们的监听器对应的回调函数。 为了最好的性能,仅设置你感兴趣的接触测试掩码中的位,也就是说通过设置接触测试掩码,你可以决定发生碰撞后,回调函数是否有响应。认值为0x00000000(所有位都被清除)。
collisionBitmask:
碰撞掩码,定义了哪些物理刚体分类可以和这个物理刚体发生碰撞。当两个物理刚体相互接触时,可能发生碰撞。这个刚体的碰撞掩码和另一个刚体的分类掩码进行逻辑与运算比较。如果结果是一个非零值,这个刚体会发生碰撞。每个刚体独立选择接受与哪个刚体发生碰撞。例如,你可以使用此掩码来忽略那些对于本刚体的速度有影响的刚体碰撞,也就是说你可以使用此掩码使得本刚体与某些刚体碰撞不会对本刚体产生影响。认值为0xFFFFFFFF(所有位都被设置)。
从上面三个掩码的说明中,我们可以做一个小结。假设刚体A的接触测试掩码和碰撞掩码已知,刚体B的分类掩码决定了能否和A进行碰撞和在碰撞的前提下能否发出PhysicsContact对象触发回调函数。如果B的分类掩码与A的碰撞掩码做逻辑与运算的结果为0,则不会发生碰撞,因此也不会继续和A的接触测试掩码进行逻辑与运算。如果B的分类掩码与A的碰撞掩码做逻辑与运算的结果非0,则发生碰撞,并且B的分类掩码继续与A的接触测试掩码做逻辑与运算,如果结果非0,则发出PhysicsContact对象触发回调函数

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是