上帝创造世界用了七天:
第一天 要有光,便有了光,把光明,黑夜分开,便有了昼夜;
第二天 有了天;
第三天 有了海和陆地,陆地是绿的;
第四天 有了太阳,月亮,和星星;
第五天 水中,空中有了生物;
第六天 陆地上有了生物;
第七天 有了人;
插了一个插曲。
上篇说完了创造一个世界,这次我们便在这个世界里加物体。
首先创造一个物体(注意不说刚体),需要再屏幕上体现出来,首先得创造一个精灵,因为刚体并不能具象的在屏幕上表示:
精灵:
CCSprite *sprite = CCSprite::create("CloseNormal.png"); sprite->setPosition(ccp(s.width/2, s.height/2)); sprite->setTag(spriteTag); addChild(sprite);
下边才是创造一个刚体:
而创造一个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拉 .大家可以看到物体落在地上。