
box2d引擎中核心的是一個叫b2world的東西,它會建立一些b2body的物體,當然這些物體的形狀有多邊形,圓形等,屬性也各異:比如密度有大有小。建立完後,在遊戲的一直調用的update函數裡加上b2world->step(),那些b2body的物體就會根據你設定的屬性有實體反應了,但是他們沒有紋理,但他們有position,rotation等屬性,我們把這屬性應用到我們cocos2d-x中的sprite屬性時,sprite就像真的物體一樣動起來了。
box2d中使用的是一個叫做b2vec2的向量。
<a target="_blank" href="http://www.waitingfy.com/archives/696#">?</a>
1
2
3
4
5
6
7
8
9
10
11
<code>b2world *_world;</code><code>//定義一個b2world指針變量,它将設定一些屬性,然後一些</code>
<code> </code><code>//物體比如圓形的方形的都将由它建立</code>
<code>b2vec2 gravity;</code>
<code> </code><code>gravity.set(0.0f, 0.0f);</code><code>//我們是在一個平面上,是以隻需要将重力加速度設定為0</code>
<code> </code><code>_world =</code><code>new</code>
<code>b2world(gravity);</code>
<code> </code><code>_world->setallowsleeping(</code><code>true</code><code>);</code>
<code> </code><code>_world->setcontinuousphysics(</code><code>true</code><code>);</code>
<code> </code><code>_collisionlistener =</code><code>new</code>
<code>collisionlistener();</code><code>//b2contactlistener,這裡可以自定義處理物體碰撞發生的事情</code>
<code> </code><code>//比如球碰到球門,我們希望重置遊戲。</code>
<code> </code><code>_world->setcontactlistener(_collisionlistener);</code>
我們主要有3種類型的b2body, dynamic, static, 和 kinematic,根據名字就知道他們的用途。
b2body建立需要一個叫b2bodydef的結構體作為參數,b2bodydef有一些屬性比如type, position,velocity,angle,等。
b2body還需要建立fixture,需要一個b2fixturedef的結構體,它也有一些屬性跟這物體相關的,比如:長寬高,半徑,還有density,elasticity,friction等屬性。下面是一個建立球的例子。
12
13
14
15
<code>b2bodydef bodydef;</code>
<code>bodydef.type = b2_dynamicbody;</code><code>//設定類型</code>
<code>b2body *body = world->createbody(&bodydef);</code>
<code>b2circleshape circle;</code><code>//建立一個圓形</code>
<code>circle.m_radius = 20.0 / ptm_ratio;</code><code>//設定半徑</code>
<code>//定義fixture</code>
<code>b2fixturedef fixturedef;</code>
<code>fixturedef.shape = &circle;</code>
<code>fixturedef.density = 1;</code>
<code>fixturedef.restitution = 0.7;</code>
<code>fixturedef.friction = 0.4;</code><code>//摩擦力</code>
<code>body->createfixture(&fixturedef);</code>
讀者可以檢視我們項目中ball.cpp中的initball,goal.cpp中的initgoal,細細體會。
我們建立了一個b2sprite類它繼承了ccsprite,有一個b2body的屬性,是以它擁有ccsprite和b2body兩個類的屬性的相加。這不是普通的ccsprite,因為它有b2body的屬性,想象下,ccsprite是負責處理一個精靈的外表,而它的内心,比如位置等方面是由實體引擎來改變的。
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<code>class</code>
<code>b2sprite :</code><code>public</code>
<code>ccsprite{</code>
<code>public</code><code>:</code>
<code> </code><code>b2sprite(gamelayer *game,</code><code>int</code>
<code>type);</code>
<code> </code><code>cc_synthesize(b2body*, _body, body);</code>
<code> </code><code>cc_synthesize(gamelayer*, _game, game);</code>
<code> </code><code>cc_synthesize(</code><code>int</code><code>, _type, type);</code>
<code> </code><code>virtual</code>
<code>void</code> <code>setspriteposition(ccpoint position);</code>
<code>void</code> <code>update(</code><code>float</code>
<code>dt);</code>
<code>void</code> <code>hide(</code><code>void</code><code>);</code>
<code>void</code> <code>reset(</code><code>void</code><code>);</code>
<code>float</code> <code>mag();</code>
<code>};</code>
<code>//兩個核心方法</code>
<code>//當你為一個精靈設定位置和旋轉角度的時候,會同樣改變它的b2body的位置和旋轉角度</code>
<code>void</code>
<code>b2sprite::setspriteposition(ccpoint position){</code>
<code> </code><code>setposition(position);</code>
<code> </code><code>if</code><code>(_body){</code>
<code> </code><code>_body->settransform(b2vec2(</code>
<code> </code><code>position.x / ptm_ratio,</code>
<code> </code><code>position.y / ptm_ratio),</code>
<code> </code><code>_body->getangle());</code>
<code> </code><code>}</code>
<code>}</code>
<code>//當精靈的b2body根據碰撞發生位置上的偏移時,會改變它的精靈的位置和旋轉角度</code>
<code>b2sprite::update(</code><code>float</code>
<code>dt){</code>
<code> </code><code>if</code><code>(_body && isvisible()){</code>
<code> </code><code>setpositionx(_body->getposition().x * ptm_ratio);</code>
<code> </code><code>setpositiony(_body->getposition().y * ptm_ratio);</code>
<code> </code><code>setrotation(cc_radians_to_degrees(-1 * _body->getangle()));</code>
總算把理論知識講的差不多了,來看看我們遊戲是如何應用box2d的。
玩家用手指頭觸摸移動的白球我們建了一個player的類,因為它是主動的,是以它的位置由觸摸點決定,但會影響b2body位置。
紅球,我們建立一個ball的類,因為它是被動的,是以它的位置由b2body決定
紅色的6根線段是b2body,它的fixture的形狀是 b2edgeshape,邊的意思,球會跟它碰撞
我們還建立了兩個球門,就是圖中兩端黑色矩形,因為與它相碰時,我們不需要改變球的b2body屬性,但需要處理事件,是以issensor設定為ture
了解上面提到的4點,我們的遊戲就那麼回事了。你可以跟沒有使用box2d的進行比較。
<a target="_blank" href="http://www.waitingfy.com/?attachment_id=700"> http://www.waitingfy.com/?attachment_id=700</a>
<a target="_blank" href="http://www.waitingfy.com/?p=696">http://www.waitingfy.com/?p=696</a>
參考:
《cocos2d-x by example beginner’s guide》