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

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

 

posted @ 2013-06-04 16:15  netxfly  阅读(993)  评论(0编辑  收藏  举报