cocos2dx 以box2d做个小车test

来源:互联网 发布:djvu阅读器 知乎 编辑:程序博客网 时间:2024/04/29 02:20

在看了一些box2d 知识后,做了个小车的demo 

在HelloWorldScene.h中,我以一个矩形作为车的主体,请看以下

    virtual bool init();      static cocos2d::CCScene* scene();    CREATE_FUNC(HelloWorld);void update(float time);virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent); //处理按下事件 virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent); //处理按下并移动事件 virtual void ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent); //处理松开事件 b2Body *ground;b2World *world;b2Body *m_car;b2Body *m_wheel1;b2Body *m_wheel2;b2WheelJoint* m_spring1;  //轮子链接b2WheelJoint* m_spring2;float32 m_hz;float32 m_zeta;float32 m_speed;b2Fixture *carbody;//车子主体b2Fixture *w1;//轮子材料b2Fixture *w2;//轮子材料b2MouseJoint *_mouseJoint;//鼠标链接bool flag;
在HelloWorldScene.cpp中的init()实现

m_hz = 4.0f;m_zeta = 0.7f;m_speed = 50.0f;        CC_BREAK_IF(! CCLayer::init());CCSize winsize=CCDirector::sharedDirector()->getWinSize();b2Vec2 vector=b2Vec2(0.0f,-10.0f);bool dosleep=true;world=new b2World(vector);world->SetAllowSleeping(dosleep);world->SetContinuousPhysics(true);b2BodyDef b2bodydef;b2bodydef.position.Set(0.0f,0.0f);ground=world->CreateBody(&b2bodydef);b2PolygonShape groundBox; //buttom groundBox.SetAsBox(winsize.width/PTM_RATIO, 0, b2Vec2(0, 0), 0); ground->CreateFixture(&groundBox, 0); // topgroundBox.SetAsBox(winsize.width/PTM_RATIO, 0, b2Vec2(0, winsize.height/PTM_RATIO), 0);ground->CreateFixture(&groundBox, 0); // left groundBox.SetAsBox(0, winsize.height/PTM_RATIO, b2Vec2(0, 0), 0);ground->CreateFixture(&groundBox, 0);// rightgroundBox.SetAsBox(0, winsize.height/PTM_RATIO, b2Vec2(winsize.width/PTM_RATIO, 0), 0);ground->CreateFixture(&groundBox, 0); flag=false;CCSprite *sprite=CCSprite::create("CloseNormal.png");this->addChild(sprite);CCSprite *sprite1=CCSprite::create("CloseNormal.png");this->addChild(sprite1);CCSprite *sprite2=CCSprite::create("rect.png");this->addChild(sprite2);b2PolygonShape chassis;chassis.SetAsBox(sprite2->getContentSize().width/PTM_RATIO/2, sprite2->getContentSize().height/PTM_RATIO/2); b2CircleShape circle;circle.m_radius = 0.4f;b2BodyDef bd;bd.userData=sprite2;bd.type = b2_dynamicBody;bd.position.Set((winsize.width/2)/PTM_RATIO, (winsize.height/2)/PTM_RATIO);m_car = world->CreateBody(&bd);carbody=m_car->CreateFixture(&chassis, 1.0f);b2FixtureDef fd;fd.shape = &circle;fd.density = 1.0f;fd.friction = 0.9f;bd.position.Set((winsize.width/2+20)/PTM_RATIO, (winsize.height/2-sprite->getContentSize().height/2)/PTM_RATIO);bd.userData=sprite;m_wheel1 = world->CreateBody(&bd);w1=m_wheel1->CreateFixture(&fd);bd.position.Set((winsize.width/2-20)/PTM_RATIO, (winsize.height/2-sprite1->getContentSize().height/2)/PTM_RATIO);bd.userData=sprite1;m_wheel2 = world->CreateBody(&bd);w2=m_wheel2->CreateFixture(&fd);b2WheelJointDef jd;b2Vec2 axis(0.0f, 1.0f);jd.Initialize(m_car, m_wheel1, m_wheel1->GetPosition(), axis);jd.motorSpeed = 0.0f;jd.maxMotorTorque = 20.0f;jd.enableMotor = true;jd.frequencyHz = m_hz;jd.dampingRatio = m_zeta;m_spring1 = (b2WheelJoint*)world->CreateJoint(&jd);jd.Initialize(m_car, m_wheel2, m_wheel2->GetPosition(), axis);jd.motorSpeed = 0.0f;jd.maxMotorTorque = 10.0f;jd.enableMotor = false;jd.frequencyHz = m_hz;jd.dampingRatio = m_zeta;m_spring2 = (b2WheelJoint*)world->CreateJoint(&jd);this->scheduleUpdate();this->setTouchEnabled(true);
这样子即可组成一个小车了

可我们要update函数,这样才可以实现车子不断地更新位置,

int velocityIterations = 8; //速度迭代,可以调整物体的运动int positionIterations = 1; //位置迭代,可以调整物体的位置,减少物体间的重叠。world->Step(time,velocityIterations,positionIterations);b2Body* node=world->GetBodyList();while(node->GetUserData()!=NULL){b2Body* b=node;node=node->GetNext();CCSprite *Sprite = (CCSprite*)b->GetUserData();Sprite->setPosition( ccp(b->GetPosition().x*PTM_RATIO,b->GetPosition().y*PTM_RATIO) );Sprite->setRotation( -1*CC_RADIANS_TO_DEGREES(b->GetAngle()) );}
在用到touch类的函数及为实现小车的点击拖移,及加一个鼠标节点。

如在void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)函数中实现

//if (_mouseJoint != NULL)   return;    CCLOG("b");CCTouch *touch = (CCTouch*)pTouches->anyObject();   //使用CCSet的方法// 获取点在视图中的坐标(左上角为原点)CCPoint location = touch->getLocation(); b2Vec2 p = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO); CCLOG("c");if(carbody->TestPoint(p))    {   CCLOG("d");b2MouseJointDef md;     md.bodyA = ground;      md.bodyB = m_car;       md.target = p;                  //移动的目标md.collideConnected = true;    //设置碰撞链接   md.maxForce = 1000.0f * m_car->GetMass();  _mouseJoint = (b2MouseJoint *)world->CreateJoint(&md);  m_car->SetAwake(true);     flag = true;  }   if (w1->TestPoint(p))   { CCLOG("e");b2MouseJointDef md;     md.bodyA = ground;         md.bodyB = m_wheel1;      md.target = p;             //移动的目标md.collideConnected = true;//设置碰撞链接md.maxForce = 1000.0f * m_wheel1->GetMass();   _mouseJoint = (b2MouseJoint *)world->CreateJoint(&md);      m_wheel1->SetAwake(true);    flag = true;  }if (w2->TestPoint(p))   { CCLOG("e");b2MouseJointDef md;     md.bodyA = ground;         md.bodyB = m_wheel2;      md.target = p;             //移动的目标md.collideConnected = true;//设置碰撞链接md.maxForce = 1000.0f * m_wheel2->GetMass();   _mouseJoint = (b2MouseJoint *)world->CreateJoint(&md);      m_wheel2->SetAwake(true);    flag = true;  }
void HelloWorld::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)中设置位置坐标

if (_mouseJoint == NULL || flag == false)   return;    CCTouch *touch = (CCTouch*)pTouches->anyObject(); //使用CCSet的方法// 获取点在视图中的坐标(左上角为原点)CCPoint location = touch->getLocation(); b2Vec2 locationWorld = b2Vec2(location.x/PTM_RATIO, location.y/PTM_RATIO);   _mouseJoint->SetTarget(locationWorld); 

void HelloWorld::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent) 

if(_mouseJoint != NULL && flag == true)  {     world->DestroyJoint(_mouseJoint);     _mouseJoint = NULL;    } 



box2d 中demo下载 点击打开链接