Box2D是一套基于刚体模拟的物理引擎,它的核心概念为世界、物体、形状、约束和关节.
void MyBox2DLayer::initLayer() { CCSize size = CCDirector::sharedDirector()->getWinSize(); this->setTouchEnabled(true); this->setAccelerometerEnabled(true);// 设置加速键 /* *Init the box2d physics */ initPhysics(); // CCSpriteBatchNode *batch = CCSpriteBatchNode::create("Images/ball-hd.png", 100); m_SpriteNode = batch->getTexture(); this->addChild(batch, 0, KSPRITE_BATCH); addAnNewSprite(ccp(size.width / 2.0f, size.height / 2.0f)); scheduleUpdate();// update the time,时刻更新物体状态 }
void MyBox2DLayer::initPhysics() { CCSize size = CCDirector::sharedDirector()->getWinSize(); b2Vec2 gravity;// step: 1 /* |^(y) gravity ,if the second param is negative number that the sprite is running down(y is decreasing)or is running up(y is increasing) | | | | |________________________________________________________>(x) (0, 0) */ gravity.Set(0.0f, -10.0f); // direction of the sprite runs,base on the GL position, world = new b2World(gravity); //step: 2 world->SetAllowSleeping(true); // pause all ,init the box2d world world->SetContinuousPhysics(true); // resume the box2d //step: 3, defint the body b2BodyDef groundbody; groundbody.position.Set(0, 0); b2Body *body = world->CreateBody(&groundbody); //step: 3, define the edge // define the 4 edges b2EdgeShape edgeBox; edgeBox.Set(b2Vec2(0, size.height / PTM_RATIO), b2Vec2(0, 0)); body->CreateFixture(&edgeBox, 0); edgeBox.Set(b2Vec2(0, 0), b2Vec2(size.width / PTM_RATIO, 0)); body->CreateFixture(&edgeBox, 0); edgeBox.Set(b2Vec2(0, size.height / PTM_RATIO), b2Vec2(size.width / PTM_RATIO, size.height / PTM_RATIO)); body->CreateFixture(&edgeBox, 0); edgeBox.Set(b2Vec2(size.width / PTM_RATIO, size.height / PTM_RATIO), b2Vec2(size.width / PTM_RATIO, 0)); body->CreateFixture(&edgeBox, 0); }
void MyBox2DLayer::addAnNewSprite(const CCPoint &point) { CCSize size = CCDirector::sharedDirector()->getWinSize(); CCNode* parent = getChildByTag(KSPRITE_BATCH); sprite = new MyBox2DSprite; sprite->initWithTexture(m_SpriteNode); sprite->setAnchorPoint(ccp(0.5f, 0.5f)); sprite->setPosition(point); parent->addChild(sprite, 1); sprite->retain(); // b2BodyDef bodydef; bodydef.type = b2_dynamicBody; // set the kind of the sprite bodydef.position.Set(point.x / PTM_RATIO, point.y / PTM_RATIO); //body b2Body *body = world->CreateBody(&bodydef); //shape b2PolygonShape dynamicShape; dynamicShape.SetAsBox(.5f, .5f); b2FixtureDef fixtureDef;//set the 精灵添加夹具 fixtureDef.shape = &dynamicShape; fixtureDef.density = 1.0f; fixtureDef.friction = 0.3f; fixtureDef.restitution = 0.8f; //set bodydef values; body->CreateFixture(&fixtureDef); sprite->setPhysicsBody(body); } void MyBox2DLayer::update(float dt) { int velocityIterations = 1; int positionIterations = 1; world->Step(dt, velocityIterations, positionIterations); }
//物体
MyBox2DSprite::MyBox2DSprite() { } void MyBox2DSprite::setPhysicsBody(b2Body * body) { m_pBody = body; } bool MyBox2DSprite::isDirty(void) { return true; } CCAffineTransform MyBox2DSprite::nodeToParentTransform(void) { b2Vec2 pos = m_pBody->GetPosition(); float x = pos.x * PTM_RATIO; float y = pos.y * PTM_RATIO; if ( isIgnoreAnchorPointForPosition() ) { x += m_tAnchorPointInPoints.x; y += m_tAnchorPointInPoints.y; } // Make matrix float radians = m_pBody->GetAngle(); float c = cosf(radians); float s = sinf(radians); if( ! CCPoint::CCPointEqualToPoint(m_tAnchorPointInPoints, CCPointZero) ){ x += c*-m_tAnchorPointInPoints.x + -s*-m_tAnchorPointInPoints.y; y += s*-m_tAnchorPointInPoints.x + c*-m_tAnchorPointInPoints.y; } // Rot, Translate Matrix m_tTransform = CCAffineTransformMake( c, s, -s, c, x, y ); return m_tTransform; }