cocos2d中使用box2d

第一步,构建一个物理世界。

b2Vec2 gravity;
gravity.Set(0.0f,-10.0f);//物理世界的重力(垂直向下掉落)
		
world = new b2World(gravity,true);//创建世界对象,true参数表示刚体可以进入睡眠模式
b2Vec2相当于cocos2d中的CGPoint,用于表示一个点。


看一下b2World的构造函数:

b2World::b2World(const b2Vec2& gravity, bool doSleep)
{
	m_destructionListener = NULL;
	m_debugDraw = NULL;

	m_bodyList = NULL;//初始化刚体列表
	m_jointList = NULL;//初始化关节列表

	m_bodyCount = 0;//世界中刚体的数量
	m_jointCount = 0;

	m_warmStarting = true;
	m_continuousPhysics = true;

	m_allowSleep = doSleep;//运动过慢的刚体 是否进入睡眠模式
	m_gravity = gravity;

	m_flags = e_clearForces;

	m_inv_dt0 = 0.0f;

	m_contactManager.m_allocator = &m_blockAllocator;
}
它初始化了数据然后返回一个b2World对象。


到这里,物理世界已经创建完毕了,可是这个世界是没有边界的,也就是说刚体可能会跳出手机屏幕之外。

只要给物理世界加4条边缘就可以了:

b2PolygonShape worldShape;

// bottom
worldShape.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));
worldBody->CreateFixture(&worldShape,0);
		
// top
worldShape.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));
worldBody->CreateFixture(&worldShape,0);
		
// left
worldShape.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));
worldBody->CreateFixture(&worldShape,0);
		
// right
worldShape.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));
worldBody->CreateFixture(&worldShape,0);
在CreateFixture函数中,通过以下代码把刚体和形状关联到一起:

b2Fixture* b2Body::CreateFixture(const b2FixtureDef* def)
{
    ...
    fixture->m_body = this;
    ...
}

第二步,向世界中加入刚体:

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;//默认是静态刚体
bodyDef.position.Set(touchPoint.x/PTM_RATIO,touchPoint.y/PTM_RATIO);
b2Body *body = world->CreateBody(&bodyDef);
CreateBody函数就是把bodyDef的内容拷贝到Body里,看看它的实现把:

b2Body* b2World::CreateBody(const b2BodyDef* def)
{
    ...
    b2Body* b = new (mem) b2Body(def, this);
    m_bodyList = b;//把刚体保存到刚体列表
    ++m_bodyCount;
    ...
}

设置形状、摩擦力、密度:

b2PolygonShape shape;
shape.SetAsBox(0.5f,0.5f);
	
b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;	
fixtureDef.density = 1.0f;
fixtureDef.friction = 0.3f;
body->CreateFixture(&fixtureDef);

第三步,更新物理世界:

在init中加入:

[self scheduleUpdate];
然后实现update函数:

- (void)update:(ccTime)dt{

	int32 velocityIterations = 8;
	int32 positionIterations = 1;
	
	world->Step(dt, velocityIterations, positionIterations);
	
	for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()) {
		if (b->GetUserData() != NULL) {
			CCSprite *spr = (CCSprite *)b->GetUserData();
			float x = b->GetPosition().x;
			float y = b->GetPosition().y;
			spr.position = ccp(x*PTM_RATIO,y*PTM_RATIO);
			spr.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
		}
	}
}

你可能感兴趣的:(cocos2d中使用box2d)