`

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

阅读更多

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



HelloBox2D实例

使用Box2D引擎进行开发过程,如图12-15所示。下面我们就按照这个步骤介绍一下代码部分。首先看一下看HelloWorldScene.h文件,它的代码如下:

[html] view plaincopy
 
  1. #ifndef __HELLOWORLD_SCENE_H__  
  2. #define __HELLOWORLD_SCENE_H__  
  3.   
  4.   
  5. #include "cocos2d.h"  
  6. #include "Box2D/Box2D.h"                                                ①  
  7.   
  8.   
  9. #define PTM_RATIO 32                                                    ②  
  10.   
  11.   
  12. class HelloWorld : public cocos2d::Layer  
  13. {  
  14.     b2World* world;                                                     ③  
  15.   
  16.   
  17. public:  
  18.     static cocos2d::Scene* createScene();  
  19.     virtual bool init();    
  20.   
  21.   
  22.     virtual void update(float dt);                                              ④  
  23.     virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event);            ⑤  
  24.   
  25.   
  26.     CREATE_FUNC(HelloWorld);  
  27.       
  28.     void initPhysics();                                                     ⑥  
  29.     void addNewSpriteAtPosition(cocos2d::Vec2 p);                               ⑦  
  30.   
  31.   
  32. };  
  33.   
  34.   
  35. #endif // __HELLOWORLD_SCENE_H__  



上述第①行代码#include "Box2D/Box2D.h"是引入使用Box2D引擎需要头文件。第②行代码#define PTM_RATIO 32是定义宏PTM_RATIO,PTM_RATIO是屏幕上多少像素为1米,32表示屏幕上32像素表示1米,在Box2D中单位使用MKS公制系统,即:长度单位采用米,质量单位采用千克,时间单位采用秒。
代码第③行world是声明物理世界b2World成员变量。第④行代码是游戏循环函数。第⑤行代码是触摸点击响应函数。第⑥行代码是声明初始化物理引擎函数initPhysics。第⑦行是声明addNewSpriteAtPosition函数,是在触摸点创建一个精灵对象。
HelloWorldScene.cpp中HelloWorld::init()函数代码如下:

[html] view plaincopy
 
  1. bool HelloWorld::init()  
  2. {  
  3.     if ( !Layer::init() )  
  4.     {  
  5.         return false;  
  6.     }  
  7.   
  8.   
  9.     Size visibleSize = Director::getInstance()->getVisibleSize();  
  10.     Vec2 origin = Director::getInstance()->getVisibleOrigin();  
  11.   
  12.   
  13.     // 初始化物理引擎  
  14.     this->initPhysics();                                                 ①  
  15.   
  16.   
  17.     setTouchEnabled(true);                                                
  18.     //设置为单点触摸  
  19.     setTouchMode(Touch::DispatchMode::ONE_BY_ONE);                            
  20.     //开始游戏循环  
  21.     scheduleUpdate();                                                   ②  
  22.   
  23.   
  24.     return true;  
  25. }  



上述代码第①行调用initPhysics()函数初始化物理引擎。第②行代码scheduleUpdate()是开始游戏循环,一旦开启游戏循环就会回调HelloWorld::update(float dt)函数。
HelloWorldScene.cpp中初始化物理引擎HelloWorld::initPhysics()函数代码如下:

[html] view plaincopy
 
  1. void HelloWorld::initPhysics()  
  2. {  
  3.     Size s = Director::getInstance()->getVisibleSize();  
  4.       
  5.     //重力参数  
  6.     b2Vec2 gravity;                                                         ①  
  7.     gravity.Set(0.0f, -10.0f);                                              ②  
  8.     //创建世界  
  9.     world = new b2World(gravity);                                           ③  
  10.     // 允许物体是否休眠  
  11.     world->SetAllowSleeping(true);                                           ④  
  12.     // 开启连续物理测试  
  13.     world->SetContinuousPhysics(true);                                       ⑤  
  14.       
  15.     //地面物体定义  
  16.     b2BodyDef groundBodyDef;                                            ⑥  
  17.     //左下角  
  18.     groundBodyDef.position.Set(0, 0);                                       ⑦  
  19.   
  20.   
  21.     //创建地面物体  
  22.     b2Body* groundBody = world->CreateBody(&groundBodyDef);                      ⑧  
  23.   
  24.   
  25.     //定义一个有边的形状  
  26.     b2EdgeShape groundBox;                                              ⑨  
  27.   
  28.   
  29.     // 底部  
  30.     groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));                        ⑩  
  31.     //使用夹具固定形状到物体上  
  32.     groundBody->CreateFixture(&groundBox,0);                                 ⑪  
  33.   
  34.   
  35.     // 顶部  
  36.     groundBox.Set(b2Vec2(0,s.height/PTM_RATIO),   
  37.                     b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));                    
  38.     groundBody->CreateFixture(&groundBox,0);                                   
  39.   
  40.   
  41.     // 左边  
  42.     groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));                           groundBody->CreateFixture(&groundBox,0);                                   
  43.   
  44.   
  45.     // 右边  
  46.     groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO),   
  47.                         b2Vec2(s.width/PTM_RATIO,0));                                 
  48.     groundBody->CreateFixture(&groundBox,0);                                   
  49.   
  50.   
  51. }  



代码第①行b2Vec2 gravity是声明重力变量,b2Vec2是一个二维矢量,它的两个属性为浮点数x和y,表示在x轴和y轴方向的矢量。第②行代码gravity.Set(0.0f, -10.0f)是设置矢量值,其中(0.0f, -10.0f)表示只有重力作用物体,-10.0f表示沿着y轴向下。
第③行代码world = new b2World(gravity)是创建物理世界b2World对象,这里采用了new创建物理世界对象,在C++中new关键字分配内存,释放内存是delete关键字。World是成员变量,需要自己释放成员变量一般是在析构函数中释放,代码如下:
HelloWorld::~HelloWorld()
{
    CC_SAFE_DELETE(world); 
}
其中CC_SAFE_DELETE(world)是安全释放world变量,CC_SAFE_DELETE宏代表安全释放内存。
第④行代码world->SetAllowSleeping(true)是允许物体睡眠与否,如果允许休眠,可以提高物理世界中物体的处理效率,只有在发生碰撞时才唤醒该对象。
第⑤行代码world->SetContinuousPhysics(true)是开启连续物理测试[ 开启连续物理测试,这是因为计算机只能把一段连续的时间分成许多离散的时间点,再对每个时间点之间的行为进行演算,如果时间点的分割不够细致,速度较快的两个物体碰撞时就可能会产生“穿透”现象,开启连续物理将启用特殊的算法来避免该现象。]。
第⑥行代码是声明形状定义(b2BodyDef)变量。第⑦行代码groundBodyDef.position.Set(0, 0)是设置形状的位置。第⑧行代码b2Body* groundBody = world->CreateBody(&groundBodyDef)是通过形状定义变量groundBodyDef创建地面物体。
第⑨行代码是声明一个有边形状定义b2EdgeShape变量,第⑩行代码groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0))是设置有边形状的开始位置(0,0)和结束位置(s.width/PTM_RATIO,0),s.width/PTM_RATIO是将像素换算成米。第⑪行代码是使用夹具固定形状到物体上。用类似的函数定义顶部、左边和右边的物体。
HelloWorldScene.cpp中创建精灵HelloWorld::addNewSpriteAtPosition函数代码如下:

[html] view plaincopy
 
  1. void HelloWorld::addNewSpriteAtPosition(Vec2 p)  
  2. {      
  3.     log("Add sprite %0.2f x %02.f",p.x,p.y);  
  4.   
  5.   
  6.     //创建物理引擎精灵对象  
  7.     auto sprite = Sprite::create("BoxA2.png");                                  ①  
  8.     sprite->setPosition( Vec2( p.x, p.y) );  
  9.     this->addChild(sprite);  
  10.   
  11.   
  12.     //物体定义  
  13.     b2BodyDef bodyDef;                                                  ②  
  14.     bodyDef.type = b2_dynamicBody;                                          ③  
  15.     bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);                         ④  
  16.     b2Body *body = world->CreateBody(&bodyDef);                              ⑤  
  17.     body->SetUserData(sprite);                                               ⑥  
  18.   
  19.   
  20.     // 定义2米见方的盒子形状  
  21.     b2PolygonShape dynamicBox;                                          ⑦  
  22.     dynamicBox.SetAsBox(1, 1);                                          ⑧  
  23.   
  24.   
  25.     // 夹具定义  
  26.     b2FixtureDef fixtureDef;                                                ⑨  
  27.     //设置夹具的形状  
  28.     fixtureDef.shape = &dynamicBox;                                         ⑩  
  29.     //设置密度  
  30.     fixtureDef.density = 1.0f;                                              ⑪  
  31.     //设置摩擦系数  
  32.     fixtureDef.friction = 0.3f;                                             ⑫  
  33.     //使用夹具固定形状到物体上    
  34.     body->CreateFixture(&fixtureDef);                                        ⑬  
  35.   
  36.   
  37. }  



上述代码第①行是创建精灵(Sprite)对象,精灵(Sprite)对象与物理引擎物体是没有关系,我们需要在游戏循环函数中更新。
代码第②行是声明动态物体定义变量,代码第③行bodyDef.type = b2_dynamicBody是设置物体类型为动态物体,物体分为静态和动态物体。第④行代码是设置物体的位置,它的单位是米。第⑤行代码b2Body *body = world->CreateBody(&bodyDef)是创建物体对象。第⑥行代码body->SetUserData(sprite)是将精灵放置到物体的UserData属性中,这样便于我们从物体中获取相关联的物体。
第⑦行代码b2PolygonShape dynamicBox是声明多边形形状定义变量。第⑧行代码dynamicBox.SetAsBox(1, 1)是设置多边形为矩形盒子形状,由于坐标原点在盒子的左下角,SetAsBox是设置盒子的中心为(1,1),那么这个盒子的就是2米见方的大小。
第⑨行代码是b2FixtureDef fixtureDef是声明夹具定义变量。第⑩行代码是设置夹具的形状。第⑪行代码fixtureDef.density = 1.0f是设置形状的密度。第⑫行代码fixtureDef.friction = 0.3f是设置摩擦系数,范围是0.0~1.0之间。第⑬行代码body->CreateFixture(&fixtureDef) 是使用夹具固定形状到物体上,这样物体就有了形状。
HelloWorldScene.cpp中游戏循环函数HelloWorld::update代码如下:

[html] view plaincopy
 
  1. void HelloWorld::update(float dt)  
  2. {  
  3.     float timeStep = 0.03f;   
  4.     int32 velocityIterations = 8;     
  5.     int32 positionIterations = 1;     
  6.   
  7.   
  8.     world->Step(timeStep, velocityIterations, positionIterations);  
  9.   
  10.   
  11.     for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())                       ①  
  12.     {  
  13.         if (b->GetUserData() != nullptr) {                                     
  14.             Sprite* sprite = (Sprite*)b->GetUserData();    
  15.             sprite->setPosition( Vec2( b->GetPosition().x *   
  16.                 PTM_RATIO, b->GetPosition().y * PTM_RATIO) );      
  17.             sprite->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );  
  18.         }  
  19.     }                                                                           ②  
  20. }  



其中代码①~②这段代码可以同步物理引擎中的物体与精灵位置和状态。

 

 

 

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


《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

京东:http://item.jd.com/11584534.html

亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

当当:http://product.dangdang.com/23606265.html

互动出版网:http://product.china-pub.com/3770734

 

《Cocos2d-x实战 C++卷》源码及样章下载地址:

源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1 

样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

欢迎关注智捷iOS课堂微信公共平台
分享到:
评论

相关推荐

    Cocos2d-x 3.x游戏开发实战pdf含目录

    同时,Cocos2d-x集成了Box2D物理引擎,使开发者能轻松实现物理效果,如碰撞检测、重力模拟等。 游戏中的音频管理也是不可或缺的一环。本书会介绍Cocos2d-x的音频API,包括音乐播放、音效处理以及音效资源的加载和...

    Cocos2d-x实战 JS卷 Cocos2d-JS开发

    3. **物理引擎**:介绍Cocos2d-x内置的Box2D物理引擎,用于模拟游戏中的碰撞检测和物理行为。 4. **事件处理**:讲解如何处理用户输入、触摸事件以及游戏内的各种交互事件。 5. **游戏逻辑**:通过实例解析如何...

    cocos2d-x box2d 物理引擎

    在cocos2d-x中,你需要创建一个Box2D的世界实例,这是所有物理模拟的基础。通过设置重力向量和其他参数,你可以控制游戏环境的物理特性。 5. **定义物理对象** 使用Box2D,你可以创建各种形状的物理对象,如矩形...

    Cocos2d-x实战 JS卷

    4. **物理引擎**:了解Cocos2d-x内置的Box2D或Chipmunk物理引擎,如何模拟真实世界的物理行为,如碰撞检测和重力。 5. **事件处理**:掌握事件监听和响应机制,包括触摸事件、键盘事件以及自定义事件的处理,实现...

    《Cocos2d-x实战 Lua卷》源码.7z

    5. **动画与物理引擎**:Cocos2d-x提供了强大的动画支持和Box2D物理引擎,源码将展示如何用Lua编写复杂的动画序列,以及如何实现物理效果,如碰撞检测、重力等。 6. **游戏逻辑**:通过实际的游戏逻辑代码,可以...

    瘸腿蛤蟆笔记42-cocos2d-x-3.2 Box2d物理引擎Motor Joint代码

    在Cocos2d-x中,Box2d的物理世界和游戏场景通常通过`cocos2d::Scene`的子类进行结合。你需要重写`update`方法,以便每帧调用`world->Step()`来执行物理模拟,同时处理Motor Joint和其他物理对象的行为。 最后,别忘...

    瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体代码

    在Cocos2d-x中,Box2D被用作一个插件,用于处理游戏对象的物理行为。要实现自由落体效果,我们需要创建一个Box2D世界,并在其中添加具有重力的边界。这可以通过以下步骤完成: 1. **初始化Box2D世界**:在Cocos2d-x...

    Cocos2d-X游戏源码大合集.rar

    Cocos2d-X集成了Box2D物理引擎,源码中可能包含如何创建物理世界、设置物理属性、实现物理碰撞的示例。 10. **调试和测试**: 源码集合可能包含调试工具和测试用例,这对于理解和改进代码质量非常有用。 通过...

    cocos2d-x 3.x游戏开发实战光盘

    《cocos2d-x 3.x游戏开发实战光盘》是一个深入探讨cocos2d-x 3.x游戏引擎开发的资源集合,旨在帮助开发者通过实际案例掌握这一强大的2D游戏开发工具。cocos2d-x是一款开源的游戏开发框架,基于C++,广泛应用于跨平台...

    cocos2d-x游戏实例-纵版射击游戏

    碰撞检测是判断子弹是否击中敌机的关键,Cocos2d-x提供了Box2D物理引擎的集成,可以用来进行精确的碰撞检测。开发者需要定义合适的碰撞形状,并处理好碰撞回调函数,以执行相应的游戏逻辑,如扣除敌人生命值、增加...

    Cocos2d-X by Example Beginner's Guide

    4. 物理引擎集成:Cocos2d-X可以与Box2D物理引擎无缝对接,用于模拟物体碰撞、重力等物理效果,为游戏添加真实感。 5. 粒子系统:内置的粒子系统让开发者可以轻松创建烟花、火焰、雪花等视觉效果,提升游戏画面的...

    cocos2d-x 实例源码

    同时,cocos2d-x内置了物理引擎Box2D,这在“愤怒的松鼠”游戏中起到了关键作用。 Box2D是一个2D物理引擎,常用于实现物体碰撞检测、重力模拟等物理效果。在“愤怒的松鼠”中,Box2D可能被用来创建松鼠、障碍物和...

    flappy bird 基于cocos2d-x 3.8

    在Cocos2d-x中,你可以通过创建`cc::Sprite`类实例来表示这些对象。鸟的飞行动画可以通过多个精灵帧来实现,而管道则可以作为静态精灵进行显示。 4. **物理引擎**:为了实现鸟的飞行效果,我们需要使用Cocos2d-x...

    cocos2d-x 11-10-20发布的

    本文将详细介绍cocos2d-x的核心特性以及如何在Linux、Win32和Android等不同平台上进行开发。 1. **cocos2d-x 框架概述** - **跨平台性**:cocos2d-x的一大优势是其跨平台能力,它支持Windows、Linux、iOS、Android...

    精通COCOS2D-X游戏开发进阶卷

    《精通COCOS2D-X游戏开发进阶卷》是一本深入探讨Cocos2d-x游戏引擎的专业书籍,旨在帮助开发者提升在Cocos2d-x框架下的游戏制作技能。Cocos2d-x是一款广泛使用的开源游戏开发框架,它基于C++,同时也支持Lua和...

    Cocos2d-x游戏开发实战精解-教学PPT

    "让人物动起来"将深入到角色的动态行为设计,讲解如何使用物理引擎(如Box2D)来实现物体碰撞检测和物理效果,创建出更真实的交互体验。 "高级UI控件"部分会探讨Cocos2d-x中的用户界面设计,包括按钮、滑块、标签等...

    Cocos2d-x实战lua卷

    在Cocos2d-x中,Lua通过tolua++或者spidermonkey等工具进行绑定,使lua脚本能够调用C++接口,实现与引擎的无缝对接。 书中可能涵盖了以下几个核心知识点: 1. **Lua基础知识**:包括变量、数据类型、表(table)的...

    cocos2dx_study.rar_cocos2d-x_cocos2d-x实例_cocos2dx

    cocos2d-x集成了Box2D物理引擎,可以创建复杂的物理模拟,如碰撞检测、重力等。熟悉Box2D的基本概念和API,可以实现真实的物理效果。 七、音频和音效 cocos2d-x支持播放背景音乐和音效,理解如何加载、播放和控制...

    Cocos2d-x 3.x游戏开发之旅_PDF电子书下载 带书签目录 高清完整版.pdf

    4. **物理引擎**:探讨Cocos2d-x内置的Box2D物理引擎,如何实现物体碰撞检测、重力模拟以及物理行为的控制。 5. **用户输入与事件处理**:解析Cocos2d-x的事件模型,如何监听和响应用户的触摸、键盘输入,以及游戏...

    Cocos2d-x高级开发教程_含书签目录_源代码

    《Cocos2d-x高级开发教程》是一本深入讲解Cocos2d-x游戏引擎的专著,适合已经对Cocos2d-x有一定基础并希望进一步提升技能的开发者阅读。Cocos2d-x是一款广泛使用的开源游戏开发框架,它基于C++,支持多平台,包括iOS...

Global site tag (gtag.js) - Google Analytics