遊戲中物理知識的應用:https://www.cnblogs.com/mumuxinfei/p/4414281.html
Box2d如何在cocos2d-x中使用簡單介紹
Box2d引擎中核心的是一個叫b2World的東西,它會創建一些b2Body的物體,當然這些物體的形狀有多邊形,圓形等,屬性也各異:比如密度有大有小。創建完後,在遊戲的一直調用的update函數里加上b2World->Step(),那些b2Body的物體就會根據你設置的屬性有物理反應了,但是他們沒有紋理,但他們有position,rotation等屬性,我們把這屬性應用到我們Cocos2d-x中的Sprite屬性時,Sprite就像真的物體一樣動起來了。
b2World設置
Box2d中使用的是一個叫做b2Vec2的向量。
1
2
3
4
5
6
7
8
9
10
11
|
b2World *_world; //定義一個b2World指針變量,它將設置一些屬性,然後一些
//物體比如圓形的方形的都將由它創建
b2Vec2 gravity;
gravity.Set(0.0f, 0.0f); //我們是在一個平面上,所以只需要將重力加速度設置爲0
_world = new b2World(gravity);
_world->SetAllowSleeping( true );
_world->SetContinuousPhysics( true );
_collisionListener = new CollisionListener(); //b2ContactListener,這裏可以自定義處理物體碰撞發生的事情
//比如球碰到球門,我們希望重置遊戲。
_world->SetContactListener(_collisionListener);
|
b2Body的創建
我們主要有3種類型的b2Body, dynamic, static, 和 kinematic,根據名字就知道他們的用途。
b2Body創建需要一個叫b2BodyDef的結構體作爲參數,b2BodyDef有一些屬性比如type, position,velocity,angle,等。
b2Body還需要創建Fixture,需要一個b2FixtureDef的結構體,它也有一些屬性跟這物體相關的,比如:長寬高,半徑,還有density,elasticity,friction等屬性。下面是一個創建球的例子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody; //設置類型
b2Body *body = world->CreateBody(&bodyDef);
b2CircleShape circle; //創建一個圓形
circle.m_radius = 20.0 / PTM_RATIO; //設置半徑
//定義fixture
b2FixtureDef fixtureDef;
fixtureDef.shape = &circle;
fixtureDef.density = 1;
fixtureDef.restitution = 0.7;
fixtureDef.friction = 0.4; //摩擦力
body->CreateFixture(&fixtureDef);
|
讀者可以查看我們項目中Ball.cpp中的initBall,Goal.cpp中的initGoal,細細體會。
b2Sprite 類
我們建立了一個b2Sprite類它繼承了CCSprite,有一個b2Body的屬性,所以它擁有CCSprite和b2Body兩個類的屬性的相加。這不是普通的CCSprite,因爲它有b2Body的屬性,想象下,CCSprite是負責處理一個精靈的外表,而它的內心,比如位置等方面是由物理引擎來改變的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
class b2Sprite : public CCSprite{
public :
b2Sprite(GameLayer *game, int type);
CC_SYNTHESIZE(b2Body*, _body, Body);
CC_SYNTHESIZE(GameLayer*, _game, Game);
CC_SYNTHESIZE( int , _type, Type);
virtual void setSpritePosition(CCPoint position);
virtual void update( float dt);
virtual void hide( void );
virtual void reset( void );
virtual float mag();
};
//兩個核心方法
//當你爲一個精靈設置位置和旋轉角度的時候,會同樣改變它的b2Body的位置和旋轉角度
void b2Sprite::setSpritePosition(CCPoint position){
setPosition(position);
if (_body){
_body->SetTransform(b2Vec2(
position.x / PTM_RATIO,
position.y / PTM_RATIO),
_body->GetAngle());
}
}
//當精靈的b2Body根據碰撞發生位置上的偏移時,會改變它的精靈的位置和旋轉角度
void b2Sprite::update( float dt){
if (_body && isVisible()){
setPositionX(_body->GetPosition().x * PTM_RATIO);
setPositionY(_body->GetPosition().y * PTM_RATIO);
setRotation(CC_RADIANS_TO_DEGREES(-1 * _body->GetAngle()));
}
}
|