学习 Box2D 个人笔记(二)b2body .

上帝创造世界用了七天:

第一天   要有光,便有了光,把光明,黑夜分开,便有了昼夜;

第二天  有了天;

第三天   有了海和陆地,陆地是绿的;

第四天   有了太阳,月亮,和星星;

第五天   水中,空中有了生物;

第六天   陆地上有了生物;

第七天   有了人;

 

插了一个插曲。

上篇说完了创造一个世界,这次我们便在这个世界里加物体。

 

 

首先创造一个物体(注意不说刚体),需要再屏幕上体现出来,首先得创造一个精灵,因为刚体并不能具象的在屏幕上表示:

精灵:

    CCSprite *sprite = CCSprite::create("CloseNormal.png");
    sprite->setPosition(ccp(s.width/2, s.height/2));
    sprite->setTag(spriteTag);
    addChild(sprite);

相信做过cocos2d 的同学很容易看懂。


下边才是创造一个刚体:

而创造一个Body(刚体),首先需要b2BodyDef  刚体的定义(包含着刚体的坐标,刚体的类型:动态),而创造一个刚体需要世界来创造。

这里说一下world里的坐标,world是个相对来说比较真实的世界,这个世界里刚体用的参数是MKS  ,也就是说米/千克/秒 ,而我们精灵用到的是像素,要相互转换,这里的PTM_RATIO也就是代表32个像素是一米,

刚体

    b2BodyDef spriteBodyDef ;
    spriteBodyDef.type = b2_dynamicBody;
    spriteBodyDef.position.Set(sprite->getPosition().x/PTM_RATIO, sprite->getPosition().y/PTM_RATIO);
    b2Body * spriteBody = world->CreateBody(&spriteBodyDef);

只是创建好一个简单的刚体需要给它设定好多参数:( 因为我设定的精灵的图片是圆形的,所以我设定的形状也是圆形的

    b2CircleShape circleShape;
    circleShape.m_radius = (sprite->getContentSize().width/2)/PTM_RATIO;//设定圆的半径
    b2FixtureDef bodyFixture;                                           //创建夹具
    bodyFixture.shape = &circleShape;                                   //设定夹具的形状
    bodyFixture.friction = 0.3;                                         //设定摩擦力
    bodyFixture.density = 1;                                            //设定密度
    bodyFixture.restitution = 0.5;                                      //设定弹力,或称为恢复系数
    
    spriteBody->CreateFixture(&bodyFixture);                            //将Body与夹具(Fixtrure)绑定
    


这样 刚体创造出来了。精灵也创造出来了 只需要一句话可以将刚体与精灵联系起来,(Body,Fixture,关节等都有一个UserData)

    spriteBody->SetUserData(sprite);

这样就可以把精灵与刚体添加在画面上。

运行一下试试?


有些失望吧。精灵不能动。没事  慢慢来 ,因为这个世界还不能动呢。我们用这种方法实现:

      scheduleUpdate();

我们用一个消息机制来实现。

然后在update 的方法里更新精灵的位置和角度


void HelloWorld::update(float dt)
{

    int velocityIterations = 8;             //速度迭代次数
    int positionIterations = 1;             //位置迭代次数
    
    world->Step(dt, velocityIterations, positionIterations);    //世界的更新
     
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext())
    {
        if (b->GetUserData() != NULL) {
            CCSprite* myActor = (CCSprite*)b->GetUserData();   //获取精灵
            myActor->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
            myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
        }    
    }
}




velocityIterations 和positionIterations 两个表示更新的参数,越大表示越精确,step表示这个世界正在更新(我是这样理解的,不对的请各位指正,谢谢)

这样大家运行一下 ,ok了吧。

只是物体一下子就掉下去了 。

于是我们要在下面加一个地面。

    b2BodyDef edgeBodydef;
    edgeBodydef.position.SetZero();
    
    b2Body *edgeBody = world->CreateBody(&edgeBodydef);    
    b2EdgeShape edgeShape ;                                     //这次用的是edgeShape
    edgeShape.Set(b2Vec2::b2Vec2(0,0), b2Vec2::b2Vec2(s.width/PTM_RATIO,0));    //设置edge  可以设置多个
    edgeBody->CreateFixture(&edgeShape, 0);                                     //将夹具加到body上
    edgeShape.Set(b2Vec2::b2Vec2(0,0), b2Vec2::b2Vec2(0,s.height/PTM_RATIO));    
    edgeBody->CreateFixture(&edgeShape, 0);                                     //body可以有好几个夹具
   


这样就ok拉 .大家可以看到物体落在地上。



你可能感兴趣的:(学习 Box2D 个人笔记(二)b2body .)