我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用物理引擎的开发过程,熟悉这些API的使用。这个实例的运行后的场景,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触摸点生成一个新的精灵,精灵的运行是自由落体运动。

HelloPhysicsWorld实例

使用物理引擎的一般步骤,如下图所示。

这个过程与上帝创建世界的过程类似,上帝首先创建了世界,然后为世界指定了边界,否则万物就会掉到世界之外的混沌里去了,最后上帝创建了万物。
当然这只是一个最基本的步骤,有的时候还需要碰撞检测和使用关节等处理。下面我们就按照这个步骤介绍一下代码部分。首先看一下看HelloWorldScene.h文件,它的代码如下:

  1. #ifndef __HELLOWORLD_SCENE_H__
  2. #define __HELLOWORLD_SCENE_H__
  3. #include "cocos2d.h"
  4. USING_NS_CC;
  5. class HelloWorld : public cocos2d::Layer
  6. {
  7. public:
  8. static cocos2d::Scene* createScene();
  9. virtual bool init();
  10. virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);            ①
  11. CREATE_FUNC(HelloWorld);
  12. void addNewSpriteAtPosition(Vec2 p);                                    ②
  13. };
  14. #endif // __HELLOWORLD_SCENE_H__

上述第①行代码是声明了单点触摸函数onTouchBegan,以便于响应单点触摸事件。第②行代码是定义创建精灵函数,这个函数是在触摸点击位置创建一个精灵对象。
HelloWorldScene.cpp中创建物理世界,代码如下:

  1. Scene* HelloWorld::createScene()
  2. {
  3. auto scene = Scene::createWithPhysics();                                    ①
  4. scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);      ②
  5. auto layer = HelloWorld::create();
  6. scene->addChild(layer);
  7. return scene;
  8. }

上述第①行代码Scene::createWithPhysics()语句是创建场景,这个是带物理引擎世界场景,使用createWithPhysics()函数会在场景中进行初始化物理引擎,我们可以通过场景的getPhysicsWorld()函数获取初始化的物理世界(PhysicsWorld)对象。我们也可以根据需要在这里设置物理世界,其中第②行代码设置在物理世界中绘制调试遮罩,这会把物体的形状绘制出来。因为世界中的物体,如果没有与精灵绑定到一起,我们是看不到它的。这主要用于调试,当调试结束后,游戏发布的时候,我们需要把它关闭。关闭绘制调试遮罩的场景如下图所示。

HelloWorldScene.cpp中指定世界的边界,代码如下:

  1. bool HelloWorld::init()
  2. {
  3. if ( !Layer::init() )
  4. {
  5. return false;
  6. }
  7. Size visibleSize = Director::getInstance()->getVisibleSize();
  8. Vec2 origin = Director::getInstance()->getVisibleOrigin();
  9. //定义世界的边界
  10. auto body = PhysicsBody::createEdgeBox(visibleSize,
  11. PHYSICSBODY_MATERIAL_DEFAULT,5.0f);                     ①
  12. auto edgeNode = Node::create();                                         ②
  13. edgeNode->setPosition(Vec2(visibleSize.width/2,visibleSize.height/2));               ③
  14. edgeNode->setPhysicsBody(body);                                      ④
  15. this->addChild(edgeNode);                                            ⑤
  16. setTouchEnabled(true);                                              ⑥
  17. //设置为单点触摸
  18. setTouchMode(Touch::DispatchMode::ONE_BY_ONE);                          ⑦
  19. return true;
  20. }

上述代码HelloWorld::init是初始化层函数,在这个函数中我们可以指定世界的边界,世界边界也是一个物体,代码第①行PhysicsBody::createEdgeBox是创建物体对象,静态函数createEdgeBox指定世界边界是矩形盒子,createEdgeBox函数的第一个参数指定矩形的大小。第二个参数是设置材质,PHYSICSBODY_MATERIAL_DEFAULT常量是默认材质,材质是由结构体PhysicsMaterial定义的,结构体PhysicsMaterial成员有:density(密度)、friction(磨擦系数)和restitution(弹性系数)。密度可以用来计算物体的质量,密度可以为零或者为正数。摩擦系数经常会设置在0.0~1.0之间,0.0表示没有摩擦力,1.0会产生强摩擦。弹性系数的值通常设置到0.0~1.0之间,0.0表示物体不会弹起,1.0表示物体会完全反弹,即称为弹性碰撞。createEdgeBox函数的第三个参数是设置边的宽度。
代码第②行是创建边界节点对象,这个节点对象作为世界边界对象,第③行代码是设置节点对象的位置。第④行代码edgeNode->setPhysicsBody(body)是设置与节点相关的物体对象。通过这条语句使得游戏场景中的节点对象(精灵等)与物体关联起来。第⑤行代码是将节点对象添加到层中。
代码第⑥行setTouchEnabled(true)是使层开始触摸事件支持。第⑦行代码setTouchMode(Touch::DispatchMode::ONE_BY_ONE)是设置触摸模式为单点触摸。
HelloWorldScene.cpp其他代码如下:

  1. bool HelloWorld::onTouchBegan(Touch* touch, Event* event)                       ①
  2. {
  3. Vec2 location = touch->getLocation();
  4. addNewSpriteAtPosition(location);
  5. return false;
  6. }
  7. void HelloWorld::addNewSpriteAtPosition(Vec2 p)                                 ②
  8. {
  9. auto sp = Sprite::create("Ball.png");                                       ③
  10. sp->setTag(1);                                                       ④
  11. auto body = PhysicsBody::createCircle(sp->getContentSize().width / 2);               ⑤
  12. //auto body = PhysicsBody::createBox(sp->getContentSize());                      ⑥
  13. sp->setPhysicsBody(body);                                            ⑦
  14. sp->setPosition(p);
  15. this->addChild(sp);
  16. }

上述代码第①行是单点触摸时候调用的函数,在这个函数中调用addNewSpriteAtPosition(location)函数,在触摸点创建一个精灵对象。
第②行代码是定义addNewSpriteAtPosition函数,第③行代码Sprite::create("Ball.png")是创建一个精灵对象,第④行代码sp->setTag(1)是设置精灵的tag属性,在检查碰撞时候可以通过tag属性判断并获得精灵对象。
第⑤行代码是通过PhysicsBody的静态createCircle函数创建圆圈形状物体。PhysicsBody还有很多类似的create函数,如createBox、createCircle、createPolygon和createEdgePolygon等函数,这些函数与物理形状对应的。这里只详细解释createCircle函数, createCircle函数API如下:
static PhysicsBody* createCircle(float radius,
const PhysicsMaterial & material = PHYSICSBODY_MATERIAL_DEFAULT,
const Vec2 & offset = Vec2::ZERO 
)
其中第一个参数radius是设置圆圈的半径,第二参数material是材质,这可以省略,默认值是PHYSICSBODY_MATERIAL_DEFAULT,所以在HelloWorld::init()函数中定义世界的边界时候,PhysicsBody::createEdgeBox语句中的material参数也是可以省略的。第三个参数offset是偏移量,可以省略,默认值是Vec2::ZERO。

第⑥行代码PhysicsBody::createBox(sp->getContentSize())是创建一个没有边的矩形盒子。第⑦行代码sp->setPhysicsBody(body)是设置与精灵相关的物体对象。

更多内容请关注国内第一本Cocos2d-x 3.2版本图书《Cocos2d-x实战:C++卷》
本书交流讨论网站:http://www.cocoagame.net
更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
欢迎加入Cocos2d-x技术讨论群:257760386

欢迎关注智捷iOS课堂微信公共平台

实例介绍Cocos2d-x物理引擎:HelloPhysicsWorld的更多相关文章

  1. Cocos2d-x教程(30)-3.x版本号物理引擎的使用

    转载时请注明原文出处 : http://blog.csdn.net/u012945598/article/details/38417333 在Cocos2d-x 2.x的版本号中,开发人员能够直接使用 ...

  2. Cocos2d-x之物理引擎

    |   版权声明:本文为博主原创文章,未经博主允许不得转载. 在很多的游戏设计中一般都会涉及和模拟到真实的物理世界.然而游戏中模拟真实世界的物理会很复杂.使用已经写好的物理引擎会用很大的帮助和便利.  ...

  3. 基于APE物理引擎的管线容积率计算方法

    容积率一般应用在房地产开发中,是指用地范围内地上总建筑面积与项目总用地面积的比值,这个参数是衡量建设用地使用强度的一项非常重要的指标.在其他行业,容积率的计算也非常重要,如产品利用率.管道使用率等等. ...

  4. 实例介绍Cocos2d-x物理引擎:碰撞检测

    碰撞检测是使用物理引擎的一个重要目的,使用物理引擎可以进行精确的碰撞检测,而且执行的效率也很高.在Cocos2d-x 3.x中使用事件派发机制管理碰撞事件,EventListenerPhysicsCo ...

  5. 实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D

    我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用.这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触 ...

  6. 实例介绍Cocos2d-x中Box2D物理引擎:使用关节

    下面我们将使用Box2D物理引擎技术进行重构.使得关节能够掌握如何在Box2D使用关节约束.HelloWorldScene.cpp中与使用关节的相关代码如下: void HelloWorld::add ...

  7. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  8. 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測

    在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...

  9. cocos2dx-3.x物理引擎Box2D介绍

    理引擎 Cocos2d-x引擎内置了两种物理引擎,它们分别是Box2D和Chipmunk,都是非常优秀的2D物理引擎,而且x引擎将它们都内置在SDK中.Box2D使用较为广泛,在这里选择Box2D来进 ...

随机推荐

  1. PostgreSQL的 initdb 源代码分析之十三

    继续分析: /* Bootstrap template1 */ bootstrap_template1(); 展开: 我这里读入的文件是:/home/pgsql/project/share/postg ...

  2. 删除链表中全部值为k的节点

    1. 问题描写叙述 给定一个单链表,删除当中值为k的全部节点.比如:1→2→6→3→4→5→61 \to 2 \to 6 \to 3 \to 4 \to 5 \to 6,删除当中值为6的节点,返回:1 ...

  3. 一个简单的小例子让你明白c#中的委托-终于懂了!

    模拟主持人发布一个问题,由多个嘉宾来回答这个问题. 分析:从需求中抽出Host (主持人) 类和Guests (嘉宾) 类. 作为问题的发布者,Host不知道问题如何解答.因此它只能发布这个事件,将事 ...

  4. Swift常用语法示例代码(二)

    此篇文章整理自我以前学习Swift时的一些练习代码,其存在的意义多是可以通过看示例代码更快地回忆Swift的主要语法. 如果你想系统学习Swift或者是Swift的初学者请绕路,感谢Github上Th ...

  5. iOS开发——实用篇Swift篇&项目开发常用实用技术

    项目开发常用实用技术 实现拨打电话 要实现打电话功能,最简单最直接的方式便是:直接跳到拨号界面 (注意:这个需要真机调试,模拟器无效果)     UIApplication.sharedApplica ...

  6. iOS开发——面试总结(一)

    面试总结(一) 通过网络搜寻和自己总结经历找了一些IOS面试经常被问道的问题: 1.搞清楚touch事件的传递(事件的响应链) 事件的响应(responder chain) 只有继承了UIRespon ...

  7. 免费的天气预报API--谷歌,雅虎,中央气象台

    Google Weather API 仅仅支持美国地区使用邮政编码进行查询,比如:  http://www.google.com/ig/api?hl=zh-cn&weather=94043  ...

  8. MYSQL-- binlog事件详解

    mysqlbinlog -vvv log.000001 # at # :: server id end_log_pos CRC32 sequence_number= SET @@SESSION.GTI ...

  9. Helpers\RainCaptcha

    Helpers\RainCaptcha This class can validate CAPTCHA images with RainCaptcha. It can generate an URL ...

  10. tar --help

    pengdl@debian:~/test$ mkdir test1 pengdl@debian:~/test$ mkdir test2 pengdl@debian:~/test$ tar -xzf p ...