《割繩子》《蠟筆物理學》《Contre Jour》《頑皮鱷魚愛洗澡》等遊戲用Box2D引擎實現物理部分的方法(轉)

從最熱門遊戲排行榜和flash遊戲網站上,你能看到什麼?許多2D遊戲都有很是出色的物理學和美術設計。如今咱們要學習那些遊戲使用了什麼物理學以及如何用Box2D製做它們。javascript

除了知道是「什麼」,更重要的是知道「如何作」,首先,我想問讀者一個問題:若是你想複製物理遊戲的機制或行爲,你須要什麼技術和方法?java

一年之前,我問了本身一樣的問題,《6 Dimensions》就是問題的答案。這款遊戲是一個創意的盒子,每一面都包含一組使用Box2D物理學再加上視覺美學技術製做的不一樣的遊戲機制。在此,我將與你們分享這款遊戲。我作這款遊戲是爲了改進遊戲引擎Codea(是由Crabitron開發的),而我寫了這篇教程是爲了向你們介紹寫實物理學、美術和遊戲設計……共同提升咱們的遊戲開發水平。node

在個人遊戲中,我設計了6個面,借一樣的思路,我將給你們介紹我運用了哪些從其餘遊戲中複製而來的物理、機制和美術技術。c++

一、形狀web

《Thomas was alone》、《憤怒的小鳥》、《蠟筆物理學》算法

點擊瀏覽下一頁

crayon physics(from gamasutra)app

在《蠟筆物理學》中,你能夠在屏幕上用手指或鼠標做畫,好比畫圓、三角形、矩形等,當你鬆開鼠標/拿開手指,線條就會變成立體物理對象(在虛擬世界中)。ide

這是怎麼作的?函數

事實上至關簡單,你要把鼠標/手指從開始到結束的繪畫路徑的各個座標點保存起來,當釋放事件發生,你就調用Box2D的一個根據這些點生成多邊形的功能:工具

local body = physics.body(POLYGON, unpack( points ) )

你得先認識一下Box2D中的有什麼形狀:

POLYGON(多邊形):

用於封閉形狀如基本幾何圖形(非圓形),它使用一系列按各個API指定的順序排列的頂點(x,y)

CIRCLE(圓):

能夠作球、水珠、星體,等等。

EDGE(邊):

用於製做牆、地面、只有起點和終點的線段。

CHAIN(鏈):

與邊相同,但你能夠閉合它(像多邊形但不是凸多邊形)或不閉合它(像邊但點超過2)

知道了剛體形狀(body shape)後,你還要了解它們的不一樣行爲,或叫做剛體類型(body types):

STATIC(靜態):如名稱所示,這種剛體會在指定的x,y(地面、牆、柱基或繩基,等等)上保持靜止不動。

DYNAMIC(動態):它與其餘對象碰撞並移動

KINEMATIC(運動):碰撞但不隨着動態對象移動,你只能經過改變它的x,y或者賦給它一個線性速度或對它施加力來使它移動。

真正的含義要在API的執行中理解,在本文中我使用這個是由於它是我能找到的最簡單的代碼了。但改變成任何語言的代碼都很是簡單,Box2D有幾乎全部的語言版本(Flash as三、c++、objc、java、javascript、java+processing,等等)。

你得保存那個功能的結果爲自定義變量如body.position(位置)、body.radius(半徑)、body.linearVelocity(線性速度)、body.angularVelocity(角速度)、body.mass(質量),等等。

當剛體制做出來時,你可能想給它定義一些屬性如restitution(恢復)、gravityScale(重力大小)和damping(衰減)等,這些屬性能夠賦給物理對象彈跳或漂浮狀態。

Box2D的複雜度固然不止這些,具備這種物理遊戲機制的其餘遊戲(《Magic Pen》)也比較復。在《Magic Pen》中,你能夠畫一些東西看起來像「node(節點)」的東西,但開發者叫它們「joint(關節)」,它們是用於鏈接剛體的,有若干種,取決於你想要的機制;還能夠用於製做鏈接着的剛體之間的行爲:

physics.joint(REVOLUTE,bodyA, bodyB,)

剛體圍繞着一個固定點(anchor)旋轉

例如:小車的車輪、《蠟筆物理學》和《Magic Pen》中的紅色節點

physics.joint( PRISMATIC, bodyA, bodyB, anchorA, direction )

在剛體各自的固定點之間保持固定距離。兩個joint之間的初始距離取決於虛擬空間中的這兩個固定點之間的初始距離。給joint設置frequency率和damping率可使它產生軟彈簧的行爲。

physics.joint(DISTANCE, bodyA, bodyB, anchorA, anchorB )

旋轉joint迫使兩個剛體沿着某兩個固定點之間的軸做運動。容許伸縮運動,但限制兩個剛體之間的相對旋轉。

physics.joint( WELD, bodyA, bodyB, anchor )

接合joint限制兩個剛體之間的運動和相對旋轉,實際上使它們變成一個剛體。由於求解器的迭代性質,當置於壓力之下時接合joint可能會變形;當承受的力太大或幾個接合joint被連接成一個更大的對象時,接合joint可能會徹底失效。

physics.joint( ROPE, bodyA, bodyB, anchorA, anchorB, maxLength )

繩子joint限制兩個剛體之間的最大距離

例如:《割繩子》中的繩子

概述:

1)建立:帶有觸點剛體或盒子或任何其餘多邊形幾何體(一組2D點:x,y),給它設置咱們須要的物理屬性(如《Thomas was alone》中的不一樣行爲),好比,若是剛體是static類型,那麼就能夠設置它的質量、密度、重力大小,等等。

2)可選屬性:依附(attach)到另外一個剛體上,好比說,你能夠把一個剛體依附到另外一個被設置爲傳感器的static剛體(不影響遊戲世界的物理,但有碰撞事件),而後激活REVOLUTE joint的enableMotor(能動)屬性,這還須要motorSpeed(速度)、maxMotorTorque(轉矩)和maxMotorForce(力量),才能肯定這個對象的旋轉狀況。

3)美術(Visual Art):有了剛體後,若是你想繪製它,不是做爲形狀繪製出來,而是具備顏色或紋理的實體,你就要把這些點三角化生成多邊形網格模型(mesh)並給它設置顏色和貼材質。

例子:

點擊瀏覽下一頁

Box2D_POLYGONS(from gamasutra)

點擊瀏覽下一頁

thomas Was Alone Boxes(from gamasutra)

對於《Thomas Was Alone》中的盒子的行爲,你能夠設置一個簡單的「juice」系統動畫(從「中間幀」演化來的),這樣,當你選擇方塊並按下跳躍鍵(或它與其餘不一樣的物理剛體發生碰撞),它就會觸發「juice command= animation」命令——產生擠壓、搖晃等動畫效果,各個動做都有本身的動畫參數,好比質量、線性速度和衰減等物理屬性。

點擊瀏覽下一頁

box Examples(from gamasutra)

對於《憤怒的小鳥》,你能夠經過給盒子定義不一樣的屬性來製做一個關卡,繪製不一樣的子畫面或製做不一樣材質的mesh,這樣,在碰撞事件中,盒子剛體就會更加生動,經過改變盒子的紋理使之與當前狀態更加協調(斷掉的木頭、快碎的玻璃,等)。

你能夠用簡單的剛體applyForce(vec2(x,y)) 函數作出小鳥的發射。各類小鳥也都有本身的質量、衰減等屬性……

二、水體

《Where is my water?》、《Sprinkle Ilsands》……

當你問網上的代碼達人,如何製做上述遊戲那樣的水體物理時,他們會跟你談Metaball(變形球):

點擊瀏覽下一頁

Metaball_contact_sheet(from gamasutra)

但在遊戲中使用Metaball技術既麻煩也不容易,並且要進行大量計算,除非你發現一些技巧和給它貼上一些美術材質。

那就是爲何運用水體物理學的遊戲並很少見。幾個月前我談到這個問題,多虧了許多人的幫助,我獲得了一個很棒的水體物理模型。在那個模型中,我用Box2D lib中的CIRCLE剛體作出動態球。

模型的代碼很容易理解,球就是物理剛體,這些剛體具備使它產生水滴行爲的參數如estitution(復原)、friction(摩擦)、damping(衰減)、linear velocity(線性速度),而後,咱們用着色器(GLSL)的技術和材質繪製這些球,須要一個mesh,就像波紋fx或使用材質的其餘GLSL着色器樣本,咱們把這個mesh的寬和高設爲整個屏幕,從中間開始:

mesh:addRect(WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)

這樣,咱們可使用各個球的位置(x,y)在虛擬空間中繪製它們,各個球都有漸變的紋理效果。

for k,b in ipairs(balls) do sprite(ballTexture, b.x, b.y) end

而後,你得使用額外的扭曲模式,給這些着色的球添加材質,並與背景混合。

例子:

點擊瀏覽下一頁

Box2D_water Physics(from gamasutra)

正如我所說的,各個球都有紋理(程序生成的漸變),能夠與其餘使用低級過濾器的球材質相融合。

點擊瀏覽下一頁

where is my water(from gamasutra)

《Where is my water?》

你能夠對各類行爲使用不一樣的層,或者把全部液體或全部動態地形作成同一層來作出相同的水體fx,而後在着色器中改變過濾值和顏色(水體、岩漿,等等)。

舉一個碰撞的例子,當兩個剛體發生碰撞時,你必須查看碰撞的bodyA和bodyB是什麼類型的剛體,若是一個是氣體(gravityScale/mass/density值其實是0,因此它會飄浮)而另外一個是「冰」,那麼你就把這個球變成水……

再舉一個例子,若是bodyA是岩漿,那麼bodyB就變成氣體……就像改變球的屬性同樣簡單,因此它會改變在box2d中響應,你要從新繪製遊戲狀態。

地形的例子:

靜態地形能夠是一個POLYGON剛體,它是用一個讀取整個地形圖象和創建一系列非透明像素的x,y (vec2)的函數製做的,而後返回給box2d函數。

動態地形能夠只是一個mesh,當你碰它時,你會移除座標x,y上的觸點,你必須用新的mesh重製這個物理剛體。

例如,當一個水滴(物理剛體CIRCLE)濺到一隻鴨子(具備激活的傳感器的物體剛體),你必須刪除那個水滴,並改變鴨子的動畫,使新狀態呈現,直到它徹底被水充滿,而後刪除鴨子並記錄結果。

水滴有很小的痕跡,這些是用linearVelocity和angularVelocity屬性繪製的,你能夠獲得方向和速度,這樣你就能夠計算痕跡的角度和距離。

事實上,你想要什麼行爲都有。

點擊瀏覽下一頁

sprinkle_islands_boss(from gamasutra)

在《Sprinkle Ilsands》中,水體着色器跟咱們所學習的那個是不一樣的,它除了使用粒子fx,還多了linearVelocity屬性。但行爲可能仍是同樣的,當水球(剛體CIRCLE)擊中火傳感器,那麼火就會熄滅,海里的水mesh也同樣。至於岩石,你能夠添加一些細節如顆粒效果等。

在這一面,咱們找不到任何joint,那就是爲何它可能沒必要要,在《Sprinkle Ilsands》,軟管就是繩子,這是咱們在下一面中要分析的。

三、橡皮筋

《Contre Jour》、《割繩子》、《水果忍者》

我花了一個月時間才作出上述遊戲的繩子原型,但我作完繩子後,我就以爲軟剛體很容易作了,由於我更加理解接頭了。

要製做一個逼真的繩子,你得建立一組剛體(CIRCLE或者POLYGON都行),把它們都依附在做爲基座的STATIC剛體上。用於結合這些繩子剛體的joint有兩種,DISTANCE或者REVOLUTE,但處於最末端(DYNAMIC)的鏈接基座(STATIC)的joint只能是製做彈力繩的ROPE joint。經過restitution 和frequency屬性來調整response(反應)/damping(衰減)/elasticity(彈性)。

例子:

點擊瀏覽下一頁

Box2D_ElasticRopes(from gamasutra)

爲了製做一個軟剛體,你得圍繞另外一箇中心剛體(能夠是STATIC或DYNAMIC)製做一系列CIRCLE剛體,它固然會影響其餘剛體,若是你改變joint的類型,你會發現這個剛體會自動變形,你必須用mesh繪製整組剛體。

點擊瀏覽下一頁

Contre-Jour(from gamasutra)

《Contre Jour》

在這款遊戲中,你能夠找到軟剛體:可變形的地形;兩種類型的繩子:彈性繩和固定繩。這些固定繩使用的技術比彈性繩的更高級。

點擊瀏覽下一頁

snotDiagram(from gamasutra)

點擊瀏覽下一頁

js Rope Segmented(from gamasutra)

《割繩子》

點擊瀏覽下一頁

cut-the-rope(from gamasutra)

這是Box2d物理作繩子的最佳案例。遊戲中的繩子也是動態的,你能夠看到沿着基座到球的mesh,球的一端是連着糖果的。

你能夠像上一個例子同樣作出這種繩子,設置球(糖果)的物理屬性—-mass、density、gravityScale,能夠作出泡泡效果。你能夠用多層混合模式繪製出泡泡。另外一種方法是把剛體變成傳感器,而且你本身的重力算法移動它,但咱們到第五面時才學習這種技術。

若是泡泡-剛體-球與青蛙或蜘蛛碰撞,或者玩家觸擊到泡泡,泡泡就會爆炸,爲此你要給泡泡添加爆炸動畫並再次改變糖果的物理屬性……

案例代碼:

if (vec2:distance( bFrog_Mouth,  bCandy ) < maxDistance) then

– 把青蛙的動畫從「空閒」改成「吃」

– 暫停輸入

– 補間並觸發遊戲結束動畫

end

四、重力

在這一面,咱們能夠發現許多使用力來對抗重力的遊戲,但這是一種遊戲玩法。例如,你能夠根據box2d的正弦函數生成簡單的地形,它會返回鏈或邊形狀的STATIC剛體。

點擊瀏覽下一頁

tiny wings 2(from gamasutra)

你能夠用Box2d作出你本身的《Tiny Wings》。基本原理就是,球(CIRCLE剛體)在重力的做用下下落,你能夠經過觸擊屏幕增長下落的linearVelocity(線性速度),當觸擊在山丘合適的部分(你能夠查看你的正弦函數的高度)釋放時,下落速度會增長……另外一種方法是隻使用力。

例子:

點擊瀏覽下一頁

Box2D_JumpRun(from gamasutra)

爲了繪製循環,給拾取、發熱狀態等添加顆粒效果。材質能夠用程序成生隨機顏色圖像作出來,用高斯噪聲添加細節、邊界,等等……

點擊瀏覽下一頁

Jetpack-Joyride(from gamasutra)

《Jetpack Joyride》

你能夠看出這款遊戲的特徵嗎?若是你已經讀過前面的例子了,那麼你應該知道角色剛體球有相同的行爲,你必定是用力對抗重力、各個飛行器的不一樣物理屬性、導彈和各類交通工具,等等。

《Madcoaster》、《Rocket Chicken》、《Whale Trail》等遊戲都是同樣的。

但這個面還有其餘機制,如行星物理、引力。

你可使用簡單的公式來模擬零重力physics.gravity(0,0),行量的吸引力以下圖所示:

點擊瀏覽下一頁

Box2D_Forces_Gravity(from gamasutra)

function Planet:attract(m) – Direction of the force local force = self.body.position – m.body.position local d     = force:len() — = m.body.position:dist(self.body.position) force = force:normalize() local dir   = vec2(self.mass/m.body.mass, self.mass/m.body.mass)

– Magnitude of the force local strength = (GRAVITY * self.mass * m.body.mass)/(d*d) force = force * strength m.body:applyForce(force)

stroke((1+math.floor(force.y))*110, (1+math.floor(force.x))*110, 10, 255)

– draw line between attractor/mover line(m.body.x+force.x, m.body.y+force.y, (self.body.x), (self.body.y)) end

這個函數會使角色球繞着行星轉。

五、線面

《拯救種子》、《蠟筆物理學》……

只有線:經過繪製線條,你能夠作出形狀類CHAIN的剛體和剛體類STATIC或DYNAMIC。

對於關卡設計,障礙物也是STATIC,能夠是EDGE或POLYGON……

點擊瀏覽下一頁

saving-seeds-hd-doodle-physics-screenshot(from gamasutra)

用那種結構,你能夠複製出一款像《拯救種子》同樣的遊戲。

點擊瀏覽下一頁

Box2D_Lines(from gamasutra)

代碼和第一面的是同樣的,但你必須改變遊戲的規則,你要從暫停的物理引擎開始,而後繪製和生成CHAIN靜止形狀,當玩家按下開始鍵時,遊戲必須生成玩家的球(以及恢復、重力、質量等參數),從新開啓物理引擎,只要一個指令(physics.pause() and physics.resume())就能完成了。

它只留在遊戲循環中,用於確認碰撞和線性速率、改變遊戲狀態……

你能夠經過打開或關閉重力,來改變整個遊戲的現實,就像《Thomas was alone》或《ibb and obb》那樣。

六、交通工具

《小輪車冒險》、《爬山賽車》

若是你已經看到這裏了,那麼作一款關於瘋狂交通工具的遊戲吧。

作交通工做,只要把接頭和輪子想成CIRCLE剛體,用錨點正確的旋轉接頭把POLYGON(小車、自行車等的形狀)和它們鏈接起來。

用帶紋理的mesh繪製自行車/小車的主要剛體、車輪的子畫面,除非你使用軟剛體作這些,不然添加痕跡、顆粒fx等。

代碼生成的例子:

點擊瀏覽下一頁

Box2D_BezierRampage(from gamasutra)

對於道路,使用一些噪點或正弦,能夠是STATIC或DYNAMIC,你可使用Bezier曲線。

點擊瀏覽下一頁

code example(from gamasutra)

《小輪車冒險》

我會知道這款遊戲和它的物理,多虧看了某人的一篇文章。

但文章做者沒有提到任何有關Box2D的東西,但我猜這款遊戲就是使用了Cocos2d(和Corona SDK)。不管如何,你如今知道怎麼製做交通工具和橫衝直撞的效果了。

在《Canvas Rider》中,有兩種自行車模型,你能夠在遊戲中改變,你會發現自行車的剛體是一個容許必定damping的接頭結構,當你改變自行車時,這個動態剛體就被破壞了,而後遊戲就生成新的自行車類型。

另外,你在遊戲中的自行車能夠觸到的線是靜態CHAIN,當你設計道路時,鼠標觸擊的是x,y……像咱們以前作的那樣。

以上。但願你能用Box2D作出一些成果。

固然,使用Box2D,經過不一樣的方法制做的遊戲還有不少,但它們可能綜合使用了上述幾種,例如,《時空幻境》、《超級食肉男孩》等,用能夠用合適的剛體、機制和着色器製做出來。

相關文章
相關標籤/搜索