Cocos2d-X Box2D的使用实例

网友投稿 230 2022-11-07

Cocos2d-X Box2D的使用实例

1、PhysicsSprite类 (1)PhysicsSprite.h #include #include "Box2D/Box2D.h" #include "cocos2d.h" USING_NS_CC; class PhysicsSprite:publicCCSprite { public:     PhysicsSprite();     void setPhysicsBody(b2Body *boddy);     int hp;//血量 private:     b2Body * m_pBody; }; (2)PhysicsSprite.cpp #include "PhysicsSprite.h" PhysicsSprite::PhysicsSprite():m_pBody(NULL) { //0与1之间的随机数     int idx=(CCRANDOM_0_1()>0.5?0:1);     int idy=(CCRANDOM_0_1()>0.5?0:1);     this->initWithFile("blocks.png",CCRectMake(32*idx, 32*idy, 32, 32));     hp=5; } void PhysicsSprite::setPhysicsBody(b2Body *boddy) {     m_pBody=boddy; } 2、MyContactListener (1)MyContactListener.h #include #include "cocos2d.h" #include "Box2D.h" USING_NS_CC; class MyContactListener:publicb2ContactListener { public:     CCLayer *_layer;     b2World *_world;     MyContactListener();     ~MyContactListener();     MyContactListener(b2World *w,CCLayer *c);          virtual void BeginContact(b2Contact* contact) ;     virtual void EndContact(b2Contact* contact) ;     virtual void PreSolve(b2Contact* contact,const b2Manifold* oldManifold);     virtual void PostSolve(b2Contact* contact,const b2ContactImpulse* impulse); }; (2)MyContactListener.cpp #include "MyContactListener.h" #include "PhysicsSprite.h" MyContactListener::MyContactListener() { } MyContactListener::~MyContactListener() { } MyContactListener::MyContactListener(b2World *w,CCLayer *c) {     _world=w;     _layer=c; } //两个物体重叠时 void MyContactListener::BeginContact(b2Contact* contact) {     CCLog("BeginContact!"); } //两个物体分离时 void MyContactListener::EndContact(b2Contact* contact) {     CCLog("EndContact!"); } void MyContactListener::PreSolve(b2Contact* contact,const b2Manifold* oldManifold) {     CCLog("PreSolve!"); } void MyContactListener::PostSolve(b2Contact* contact,const b2ContactImpulse* impulse) {     CCLog("PostSolve!");     float force=impulse->normalImpulses[0];     if(force>2)     {         PhysicsSprite *spriteA=(PhysicsSprite *)contact->GetFixtureA()->GetBody()->GetUserData();         PhysicsSprite *spriteB=(PhysicsSprite *)contact->GetFixtureB()->GetBody()->GetUserData();         if(spriteA && spriteB)         {                         spriteA->hp--;             spriteB->hp--;         }     } } 3、b2World (1)b2World.h #include #include "Box2D.h" #include "cocos2d.h" USING_NS_CC; class World:public CCLayer { public:     virtual bool init();     static CCScene *scene();     CREATE_FUNC(World);          void update(float dt);     void initPhysical();     void addNewSpriteAtPosition(CCPoint position);          virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent);     virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent);     virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent);          CCLabelTTF *label1;     CCLabelTTF *label2; private:     b2World *world;      }; (2)b2World.cpp #include "b2World.h" #include "PhysicsSprite.h" #include "MyContactListener.h" CCScene *World::scene() {     CCScene *scene=CCScene::create();     World *w=World::create();     scene->addChild(w);     return scene; }  bool World::init() {     if(!CCLayer::init())     {         return false;     }     //CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);              label1=CCLabelTTF::create("0","Arial", 30);     label1->setPosition(ccp(240,160));     this->addChild(label1);               initPhysical();          MyContactListener *listener=newMyContactListener(world,this);     world->SetContactListener(listener);     this->setTouchEnabled(true);     this->setTouchMode(kCCTouchesOneByOne);               this->scheduleUpdate();     return true; } void World::update(float dt) {     int velocityIteration=8;//8次速度     int positionIteration=1;//一次位置     world->Step(dt, velocityIteration, positionIteration);          b2Body *b=world->GetBodyList();     while(b)     {         b2Body *p=b;         b=b->GetNext();         if(p->GetUserData() !=NULL)         {             PhysicsSprite *myActor=(PhysicsSprite *)p->GetUserData();             if(myActor->hp<0)             {                 myActor->removeFromParent();                 world->DestroyBody(p);             }             myActor->setPosition(CCPointMake(p->GetPosition().x*32, p->GetPosition().y*32));             myActor->setRotation(-1*CC_RADIANS_TO_DEGREES(p->GetAngle()));         }     }     /*     for(b2Body *b=world->GetBodyList();b;b->GetNext() )     {         if(b->GetUserData() != NULL)         {             PhysicsSprite *myActor=(PhysicsSprite *)b->GetUserData();             if(myActor->hp<0)             {                 myActor->removeFromParent();                 world->DestroyBody(b);             }             myActor->setPosition(CCPointMake(b->GetPosition().x*32, b->GetPosition().y*32));             myActor->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle()));         }     }      */ } //初始化 void World::initPhysical() {     CCSize winSize=CCDirector::sharedDirector()->getWinSize();     b2Vec2 gravity;//设置重力(结构体)     gravity.Set(0.0f, -10.0f);     //创建世界     world=new b2World(gravity);     world->SetAllowSleeping(true);//设置睡眠     world->SetContinuousPhysics(true);//设置连续碰撞     //创建刚体(结构体)     b2BodyDef groundBodyDef;     groundBodyDef.position.Set(0.0f,0.0f);     b2Body *groundBody=world->CreateBody(&groundBodyDef);      //创建形状(结构体)     b2EdgeShape groundBox;     //bottom     groundBox.Set(b2Vec2(0,0), b2Vec2(winSize.width/32,0));     groundBody->CreateFixture(&groundBox,0);     //top     groundBox.Set(b2Vec2(0, winSize.height/32),b2Vec2(winSize.width/32,winSize.height/32));     groundBody->CreateFixture(&groundBox,0);     //left     groundBox.Set(b2Vec2(0,0), b2Vec2(0,winSize.height/32));     groundBody->CreateFixture(&groundBox,0);     //right     groundBox.Set(b2Vec2(winSize.width/32,0), b2Vec2(winSize.width/32,winSize.height/32));     groundBody->CreateFixture(&groundBox,0);//填充 } void World::addNewSpriteAtPosition(CCPoint position) {     PhysicsSprite *sprite=newPhysicsSprite();     sprite->setPosition(position);     this->addChild(sprite);          b2BodyDef bodyDef;//创建刚体     bodyDef.type=b2_dynamicBody;//设置类型     bodyDef.position.Set(position.x/32, position.y/32);     bodyDef.userData=sprite;//刚体与精灵链接          b2Body *body=world->CreateBody(&bodyDef);     b2PolygonShape dynamicBox;//多边形     dynamicBox.SetAsBox(0.5f,0.5f);//指定形状为长方形     b2FixtureDef fixtureDef;//关联     fixtureDef.shape=&dynamicBox;//形状     fixtureDef.density=10.0f;//密度     fixtureDef.friction=0.0f;//摩擦          fixtureDef.restitution=1.0f;//恢复     body->CreateFixture(&fixtureDef);//刚体创建夹具     sprite->setPhysicsBody(body); } bool World::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) {     return true; } void World::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) { } void World::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) {     this->addNewSpriteAtPosition(pTouch->getLocation()); } 注意:  1、b2BodyDef与b2FixtureDef的区别:     //b2BodyDef是用来存放刚体在世界中的数据,比如position(x,y) , angle 等等属性。    // b2FixtureDef则是用来存放刚体自身的数据,比如shape(polygonShape,等等),density,friction等等属性。 2、step方法要传递三个参数,dt,velocityIterations, positionIterations: 即world->Step(dt, velocityIteration, positionIteration):   dt,时步。通常建议设置为1/60,这样的话你的fps最好也设置到60。但是我发现更好的办法就是把timeStep设置为fps的倒数即可。如果你的fps是30,那么就设置为1/30。  (1)velocityIterations,速度迭代  (2) positionIterations,位置迭代: 这两个值通常建议设置为10,更低的迭代值会让你牺牲一些准确性,相反的为你的程序提升一部分性能。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python的PyCoral迎来多项更新,为边缘AI注入更多精彩
下一篇:jdk8使用stream实现两个list集合合并成一个(对象属性的合并)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~