cocos2d-x中的Box2D物理引擎
在Cocos2d-x中集成了2个物理引擎,一个是Chipmunk,一个是Box2D。前者是用C语言编写的,文档和例子相对较少;Box2D是用C++写的,并且有比较完善的文档和资料。所以在需要使用物理引擎的时候,大多数开发者会选择Box2D。Box2D是一款用来模拟刚体在物理世界运动的仿真引擎。通过Box2D物理引擎,世界中的物体就可以按照运动定律进行运动。
注:Box2D下的类都是以b2为前缀的,希望不要与你的命名相冲突
1. 首先我们介绍下需要用到的基本概念。
世界(world) :世界代表了一个遵循物理规律的空间,所有的物体都在世界中运动,世界具有创建销毁刚体,创建销毁关节等功能
刚体(body) :一块十分坚硬的物质,它上面的任何两点之间的距离都是完全不变的。刚体具体划分为静态刚体,动态刚体和棱柱刚体(漂浮刚体)
形状(shape):一块严格依附于刚体(body)的 2D 碰撞几何结构(collision geometry)。形状通过关联附加到刚体上,这样刚体就具备了视觉上的外形。
关节(joint):它是一种用于把两个或多个物体固定到一起的约束。Box2D 支持的关节类型有:旋转,棱柱,距离等等。关节可以支持限制(limits)和马达(motors)
关节限制(joint limit):一个关节限制(joint limit)限定了一个关节的运动范围。例如人类的胳膊肘只能做某一范围角度的运动
关节马达(joint motor):一个关节马达能依照关节的自由度来驱动所连接的物体。例如,你可以使用一个马达来驱动一个肘的旋转
2. 我们现在来简单的使用下Box2D,体验一下模拟的物理世界
(1)首先需要创建世界,创建世界需要两个步骤,首先生成重力向量,然后根据重力向量生成世界
bool HelloWorld::init()
{
if ( !CCLayer::init() )
{
return false;
}
// b2Vec2带的两个参数是表示x,y方向的重力大小,正负表示方向
b2Vec2 gravity(0.0f,-10.0f);
// 创建Box2D的世界
world = new b2World(gravity);
// 设置刚体休眠(当刚体到达边界的时候,停止对刚体的计算,节约CPU)
world->SetAllowSleeping(true);
// 使用连续的物理检测
world->SetContinuousPhysics(true);
// 注册碰撞检测的监听
world->SetContactListener(this);
// 创建漂浮刚体
addBird(1, 3.33, b2_kinematicBody);
// 创建静态刚体
addGrass(5.0, 0.5, b2_staticBody);
// 设置屏幕可以触摸
setTouchEnabled(true);
// 开辟线程回调模拟
this->scheduleUpdate();
return true;
}
(2)创建非静态刚体
void HelloWorld::addBird(float x,float y,b2BodyType objectType)
{
/***** 构建刚体的参数(包括位置,类型) *****/ // 定义刚体用到的精灵
CCSprite *sprite = CCSprite::create("bird.png");
addChild(sprite); // 配置刚体的定义(类似隐形,没有肉体的刚体)
b2BodyDef def;
def.position = b2Vec2(x, y); // 设置位置
def.type = objectType; // 配置刚体的类型,分为三类:静态刚体,漂浮刚体,动态刚体
if (objectType == b2_kinematicBody) {
def.linearVelocity = b2Vec2(2, 0); // 两个参数分别代表横向速度和纵向速度
} // 定义形状(此处为多边形)
b2PolygonShape birdShape;
// 定义边界(世界边界),参数是半宽,半高,因为生成的大小是其传入参数的2倍
birdShape.SetAsBox(sprite->getContentSize().width / RATIO / 2, sprite->getContentSize().height / RATIO / 2); // 配置刚体的体积(材料(有肉的实体))
b2FixtureDef fixtureDef;
fixtureDef.density = 1; // 密度
fixtureDef.friction = 0.3; // 摩擦因数
fixtureDef.restitution = 0.8f; // 反弹效果
fixtureDef.shape = &birdShape; // 配置刚体的实体 /***** 构建刚体的形体 *****/ // 创建刚体
birdBody = world->CreateBody(&def); // 将材料加入到刚体里
birdBody->CreateFixture(&fixtureDef); // 绑定精灵到刚体
birdBody->SetUserData(sprite);
}
(3) 添加静态刚体
void HelloWorld::addGrass(float x,float y,b2BodyType objectType)
{
/***** 构建刚体的参数(包括位置,类型) *****/ // 定义刚体用到的精灵
CCSprite *sprite = CCSprite::create("grass.png");
addChild(sprite,1); // 配置刚体的定义(类似隐形,没有肉体的刚体)
b2BodyDef def;
def.position = b2Vec2(x, y); // 设置位置
def.type = objectType; // 配置刚体的类型,分为三类:静态刚体,漂浮刚体,动态刚体 // 定义形状(此处为多边形)
b2PolygonShape grassShape;
// 定义边界(世界边界),参数是半宽,半高,因为生成的大小是其传入参数的2倍
grassShape.SetAsBox(sprite->getContentSize().width / RATIO / 2 , sprite->getContentSize().height / RATIO / 2); // 配置刚体的体积(材料(有肉的实体))
b2FixtureDef fixtureDef;
fixtureDef.density = 1;
fixtureDef.friction = 0.3;
fixtureDef.shape = &grassShape; // 配置刚体的实体 /***** 构建刚体的形体 *****/ // 创建刚体
grassBody = world->CreateBody(&def); // 将材料加入到刚体里
grassBody->CreateFixture(&fixtureDef); // 绑定精灵到刚体
grassBody->SetUserData(sprite); }
(4)驱动模拟世界
// 世界类用于驱动模拟
void HelloWorld::update(float a)
{
float32 timeStep = 1.0f / 60.f;
// Step()函数的第一个参数是时间步数,后面两个参数分别是速度阶段和位置阶段
world->Step(timeStep, 8, 3); CCSprite *s; for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()) {
if (b->GetUserData() != NULL) {
s = (CCSprite*)b->GetUserData();
// 漂浮刚体的运动模拟
s->setPosition(ccp(b->GetPosition().x * RATIO, b->GetPosition().y * RATIO));
if (s->getPosition().x < -10 || s->getPosition().x > 490 || s->getPosition().y < -10) {
this->removeChild(s);
world->DestroyBody(b);
}
}
}
}
(5)设置屏幕可以触摸,实现触摸屏幕添加刚体的效果
void HelloWorld::registerWithTouchDispatcher(void)
{
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 1, false);
}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
CCPoint p = pTouch->getLocation(); addBird(p.x / RATIO, p.y / RATIO, b2_dynamicBody); return true;
}
(6)让HelloWorld类继承b2ContactListener,重写BeginContact函数,实现刚体的检测碰撞
// 碰撞检测
void HelloWorld::BeginContact(b2Contact* contact)
{
if ((contact->GetFixtureA()->GetBody() == grassBody || contact->GetFixtureB()->GetBody() == grassBody)) {
CCLog("有鸟落在草地上!");
} else {
CCLog("鸟与鸟之间发生碰撞");
}
}
效果如图所示:

cocos2d-x中的Box2D物理引擎的更多相关文章
- 实例介绍Cocos2d-x中Box2D物理引擎:HelloBox2D
我们通过一个实例介绍一下,在Cocos2d-x 3.x中使用Box2D物理引擎的开发过程,熟悉这些API的使用.这个实例运行后的场景如图所示,当场景启动后,玩家可以触摸点击屏幕,每次触摸时候,就会在触 ...
- 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检测
在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...
- 实例介绍Cocos2d-x中Box2D物理引擎:碰撞检測
在Box2D中碰撞事件通过实现b2ContactListener类函数实现,b2ContactListener是Box2D提供的抽象类,它的抽象函数:virtual void BeginContact ...
- 实例介绍Cocos2d-x中Box2D物理引擎:使用关节
下面我们将使用Box2D物理引擎技术进行重构.使得关节能够掌握如何在Box2D使用关节约束.HelloWorldScene.cpp中与使用关节的相关代码如下: void HelloWorld::add ...
- python下的Box2d物理引擎的配置
/******************************* I come back! 由于已经大四了,正在找工作 导致了至今以来第二长的时间内没有更新博客.向大家表示道歉 *********** ...
- 【极客学院出品】Cocos2d-X系列课程之九-BOX2D物理引擎
Cocos2d-x 是时下最热门的手游引擎,在国内和国外手机游戏开发使用的份额各自是70%和25%,在App Store的top10中,有7个是用它开发的. 本节课程为Cocos2d-x系列课程之九, ...
- 瘸腿蛤蟆笔记29-cocos2d-x-3.2 Box2d物理引擎dynamics模块介绍
转载标明出处:http://blog.csdn.net/notbaron/article/details/38611335 上篇回想 本篇名言:奋斗.寻觅.发现,而不屈服.[诗人丁尼生] 上篇中,我们 ...
- Egret中使用P2物理引擎
游戏中的对象按照物理规律移动,体现重力.引力.反作用力.加速度等物体特性,实现自由落体.摇摆运动.抛物线运动,以及物理碰撞现象的模拟.用于模拟物理碰撞.物理运动的引擎称为物理引擎. 来自瑞典斯德哥尔摩 ...
- libgdx学习记录18——Box2d物理引擎
libgdx封装了Box2D物理引擎,通过这个引擎能够模拟物理现实,使设计出的游戏更具有真实感. libgdx中,Box2d程序的大概过程: 1. 创建物理世界world,并设置重力加速度. 2. 创 ...
随机推荐
- XHTML 结构化:使用 XHTML 重构网站
http://www.w3school.com.cn/xhtml/xhtml_structural_01.asp 我们曾经为本节撰写的标题是:"XHTML : 简单的规则,容易的方针.&qu ...
- HTML5简单入门系列(二)
前言 上篇中写到HTML5中的画布(canvas)元素,查看了canvas其他的资料,发现这个元素相关内容太多,鉴于本系列只是基础(主要是LZ也是初学),不再做太多介绍,有机会的话再单独写相关内容.说 ...
- BeanUtils包的学习
BeanUtils支持八种基本数据类型(int double short char byte float boolean long)的反射,对于日期需要提前注册DateLocalConvert获取转换 ...
- [TYVJ] P1030 乳草的入侵
乳草的入侵 背景 Background USACO OCT09 6TH 描述 Description Farmer John一直努力让他的草地充满鲜美多汁的而又健康的牧草.可惜天不从人愿,他在植物 ...
- 常用两种数据交换格式之XML和JSON的比较
目前,在web开发领域,主要的数据交换格式有XML和JSON,对于XML相信每一个web developer都不会感到陌生: 相比之下,JSON可能对于一些新步入开发领域的新手会感到有些陌生,也可能你 ...
- keil在WIN7下的破解
win7好看的界面和不错的性能,被越来越多的人所接受并使用.对于学电子的人来说,往往要用到专业方面的软件如Keil.下面以Keil C51 V9.00 即最新版本uVision 4在win7下的破解为 ...
- QT自定义窗口(模拟MainWindow)
在这里自定义窗口是通过继承于QFrame,内部分为上下两部分,上半部分就是标题栏,下面是窗口的具体内容.上下两部分通过布局固定位置.最后窗口的各种鼠标拖动,缩放,等操作通过添加鼠标事件来完成一个窗口的 ...
- C#.Net前台线程与后台线程的区别
本文来自:http://www.cnblogs.com/zfanlong1314/archive/2012/02/26/2390455.html .Net的公用语言运行时(Common Languag ...
- TRIZ系列-创新原理-32-改变颜色原理
改变颜色原理的详细描写叙述例如以下:1)改变物体或其环境的颜色:2)改变物体或其环境的透明度:3)对于难以看到的物体或过程.使用颜色加入剂来观測.4)假设已经使用了这样的加入剂,那么使用发光跟踪或原子 ...
- SPOJ 130 - Rent your airplane and make money(dp+优化)
题意:有n列预定航班,从st时刻开始出发,飞行时间为d,花费为p,且同一时刻不能有两个航班,求最大的花费 对航班的开始时间(或结束时间)按升序排序,从后往前找到对应结束时间所在的航班位置(如按结束时间 ...