您的位置:首页 > 移动开发 > Cocos引擎

「cocos2d-x」物理引擎学习之box2D(1)

2013-06-04 16:15 429 查看
Cocos2d中提供了2种物理引擎,分别为Box2d和chipmunk,Box2d是C++实现的,Chipmunk是C实现的,因为Box2d是面向对象的,所以一般使用Box2d的比较多,另外Chipmunk也有Objective-c版的。

Box2d物理引擎比较复杂,本次只写简单的物理世界、静态及动态钢体的创建。

Box2D中的一些概念

刚体:物体中的一种,和我们在物理中学习的刚体的概念是一样的,物体上2个间之间的距离都是完全不会变化的。不会发生变形。他就是Box2D中的body。刚体有3种:动态刚体,静态和棱柱钢体。

形状:一个依附于body的几何结构体,同时具有物理的摩擦(friction)和恢复(restitution)的材料性质。

约束:就是我们所熟悉的自由度(横纵坐标2个方向及自身的旋转)

世界:Box2d的容器,里面包括物体及他们之间的相互作用

创建一个物理世界

  //定义重力参数,纵向的重力加速度为-10.0f
b2Vec2 gravity;
gravity.Set(0.0f, -10.0f / 6.0f);        //模拟月球的重力

_world = new b2World(gravity);            //创建世界对象

_world->SetAllowSleeping(true);            //允许休眠
_world->SetContinuousPhysics(true);        //设置检测连续碰撞


创建一个静态的地形钢体,防止动态和棱柱钢体掉出屏幕之外

  //定义地形钢体描述并设置坐标为左下角
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0);
//根据钢体的描述创建钢体对象
b2Body* groundBody = _world->CreateBody(&groundBodyDef);
groundBody->SetType(b2_staticBody);

b2EdgeShape groundBox;        //定义地面盒形状

//2个点确定一条线,以下分别设置了屏幕的4个边
// bottom
groundBox.Set(b2Vec2(0, 0), b2Vec2(_ScreenSize.width/PTM_RATIO, 0));
groundBody->CreateFixture(&groundBox,0);

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

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

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


创建一个动态刚体(篮球):

//定义一个动态钢体
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(_ScreenSize.width * 0.5 / PTM_RATIO, _ScreenSize.height * 0.5 / PTM_RATIO);

b2Body *ballbody = _world->CreateBody(&bodyDef);

ballbody->SetUserData(this->getBall());
ballbody->SetActive(true);

//给这个动态钢体创建盒子形状
b2PolygonShape dynamicBox;
dynamicBox.SetAsBox(.5f, .5f);

//为该钢体定义夹具
b2FixtureDef fixtureDef;
fixtureDef.shape = &dynamicBox;        //绑定物体的形状
fixtureDef.density = 10.0f;            //密度
fixtureDef.restitution = 0.9f;        //弹性系数
fixtureDef.friction = 0.3f;            //摩擦力
//在刚体的夹具工厂中创建夹具
ballbody->CreateFixture(&fixtureDef);


钢体的状态更新需要在定时器中完成

void HelloWorld::update(float dt)
{
int velocityIterations = 8;
int positionIterations = 1;

//时间定义成固定的,如果用dt的话,会随着帧率的变化而变化
_world->Step(0.2f, velocityIterations, positionIterations);

//枚举世界中的所有物体,找出有userdata的物体,强制转化为精灵
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext())
{
if (b->GetUserData() != NULL)
{
CCSprite *sprite = (CCSprite *)b->GetUserData();
if (sprite != NULL)
{
//获取物体的坐标并转换成cocos2d的坐标
b2Vec2 bodyPos = b->GetPosition();
CCPoint pos = ccp(bodyPos.x * PTM_RATIO, bodyPos.y * PTM_RATIO);
float32 rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());        //转换角度
sprite->setPosition(pos);        //设置精灵坐标
sprite->setRotation(rotation);    //设置精灵角度
}
}
}

}


完整代码下载地址:http://vdisk.weibo.com/s/EiAqz
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: