[原创]cocos2d-x研习录-第三阶 特性之物理引擎

游戏物理引擎是指在游戏中涉及物理现象的逻辑处理,它用于模拟现实世界的各种物理规律(如赛车碰撞、子弹飞行、物体掉落等),让玩家能够在游戏中有真实的体验。

Cocos2D-x中支持Box2D和Chipmunk两种第三方开源物理引擎。这两种物理引擎功能上没有本质的区别,只是Chipmunk是用C语言实现的,Box2D是用C++语言实现的。Box2D目前相对使用更为广泛,所以本节只了解Box2D物理引擎。

要学习Box2D物理引擎,我们先来了解一些Box2D中定义的重要概念,这些概念是构成Box2D世界的基础,它的重要性不言而喻。

·刚体(rigid body):不会发生形变的物体,其任何两点间的距离是不变的。

·形状(shape):依附于物体的二维的形状结构,具有摩擦和恢复的材料属性。

·约束(constraint):约束就是限制物体*的物理连接。在二维中,物体有三个*度,比如把一个物体固定在墙上,它只能绕着固定的点旋转,它失去了两个*度。

·接触约束(contact constraint):自动创建的约束,防止刚体穿透、模拟摩擦和恢复的特殊约束,不需要手动创建。

·关节(joint):把两个物体固定在一起的约束,包括旋转、距离和棱柱等、关节可以支持限制和马达。

·关节马达(joint motor):一个关节马达依靠*度来驱动物体,比如使用马达来驱动旋转。

·关节限制(joint limit):限制关节的运动范围如同人的胳膊只能在一定范围内运动一样。

·世界(world):物体、形状和约束互相作用形成的世界。允许创建多个世界。

我们这里就不去关注Box2D的实现,而重点放在Box2D在Coco2D-x中的使用。Box2D物理引擎的使用步骤大致如下:

1)创建一个物理世界,同时设置其参数;

2)创建刚体地面,定义一个形状,把它绑定在刚体上;

3)创建世界中的其他刚体和约束等;

4)在游戏的逻辑循环中加入物理引擎的世界更新函数。

整个过程的主要目的就是将负责渲染的Cocos2D-x引擎部分和负责物理逻辑的Box2D部分结合在一起。这也是在其他平台上使用Box2D时需要做的事情,其中创建刚体、约束和关节等是最关键的部分,也是和渲染的Cocos2D-x引擎部分结合的关键部分。

在Cocos2D-x中使用Box2D,主要是将Cocos2D-x中负责渲染的节点类对象和Box2D中负责物理模拟的对象"绑定"在一起,实现逻辑和渲染的模拟。

下面我们根据以上使用步骤,结合代码查看一下的使用方法。

b2Vec2 gravity; //定义物理世界的重力系统
    gravity.Set(0.0f, -10.0f);//设置重力大小和方向
    b2World* world = new b2World(gravity); //创建物理世界对象

world->SetAllowSleeping(true);//是否允许休眠

world->SetContinuousPhysics(true);

b2BodyDef groundBodyDef; //定义物体对象类型
    groundBodyDef.position.Set(0, 0);

b2Body* groundBody = world->CreateBody(&groundBodyDef); //创建物体对象    //定义物体边界

b2EdgeShape groundBox;

groundBox.Set(b2Vec2(0,0), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);

groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

groundBox.Set(b2Vec2(0,s.height/PTM_RATIO), b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);

groundBox.Set(b2Vec2(s.width/PTM_RATIO,s.height/PTM_RATIO), b2Vec2(s.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);

以上代码完成了步骤1)和2),下面进入步骤3和4),这是将Box2D与Cocos2D结合在一起的关键部分,一起来看一看吧。

PhysicsSprite *sprite = new PhysicsSprite();

sprite->initWithTexture(m_pSpriteTexture, CCRectMake(32 * idx,32 * idy,32,32));

sprite->autorelease();

这里是创建一个精灵对象,这里物理精灵类PhysicsSprite是自定义类,它继承于CCSprite,定义它的作用就是将渲染精灵类与刚体对象绑定在一起。

b2BodyDef bodyDef;
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(p.x/PTM_RATIO, p.y/PTM_RATIO);

b2Body *body = world->CreateBody(&bodyDef);//定义物体边界

PolygonShape dynamicBox;
    dynamicBox.SetAsBox(.5f, .5f);
    b2FixtureDef fixtureDef;
    fixtureDef.shape = &dynamicBox;   
    fixtureDef.density = 1.0f;
    fixtureDef.friction = 0.3f;
    body->CreateFixture(&fixtureDef);

sprite->setPhysicsBody(body);//将刚体添加到刚体精灵对象中

接下来就是Box2D的动画更新,它是在时间调度的update中更新动画的。最后,就是更新渲染方法,在自定义类PhysicsSprite中的nodeToParentTransform方法更新节点位置。

物理引擎的内容还有很多,这里只是抛砖引玉的介绍一下。

-------------------------------------------------------------------------------------------------------------------

注:本人在本博客的原创文章采用创作共用版权协议http://creativecommons.org/licenses/by-nc-sa/2.5/cn/), 要求署名、非商业用途和保持一致。要求署名包含注明我的网名及文章来源(我的博客地址:http://www.cnblogs.com/binbingg)。

上一篇:[转帖]curl网站开发指南


下一篇:[原创]cocos2d-x研习录-第二阶 概念类之精灵类(CCSprite)