1. 程式人生 > >cocos2dx物理引擎和碰撞檢測(六)物體Bodies

cocos2dx物理引擎和碰撞檢測(六)物體Bodies

前面已經講到形狀和框架的含義,它們分別是用來進行碰撞檢測和物理模擬的物件。到現在我們建立的物理世界當中,還未存在任何的物體。因此接下來的內容就介紹物理世界的主角:物體(Body)。它是構成世界的主要因素,因為不僅框架,形狀會依附於物體,就連後面介紹的關節也是要繫結在物體之上的。

物體定義:
Box2D引擎的物體都為剛體,它的形狀不為任何外力所改變。物體上面的任何兩點之間的距離都是完全不變的。它具有質量和慣性。它的運動狀態由重力和受力決定。它的動態移動由線速度和角速度控制。物體分3類:

(1)靜態物體(b2_staticBody) 質量為0,在模擬時,靜態不可移動,就好像它具有無窮大的質量。不過,靜態物理可以讓使用者手動的移動,它速度為0。這也就是說其移動的位置由使用者控制。另外,它也不會和其他靜態或者平臺物體相互碰撞。它常常被用來實現遊戲中的地面,邊界等元素。

(2)平臺物體(b2_kinematicBody)是按照固定軌跡在做運動的物體,其質量也為0,與靜態物體一樣,平臺物體也可以被使用者移動。通常情況下開發者會預設一個速度。它也不會和其他的靜態或者平臺物體碰撞。平臺物體常常用來表示遊戲中的電梯、平臺、橋等等。

(3)動態物體(b2_dynamicBody)是遊戲中最常見的精靈物件對應的物體,具備質量、速度、摩擦等。它參與引擎當中的碰撞檢測和物理模擬。它們可以讓使用者手動移動,但通常它們都是受力的作用而運動。動態物體可以與物理世界中任何物件發生碰撞。

上述物體的型別都可以被施加外力(forces)、扭陣(torques)以及衝量(impuless)。但是因為靜態和平臺物體的質量為無窮大,所以並不會發生狀態的改變。因此在遊戲當中,被施加外力的經常是動態物體。

在物理世界當中,物體物件就是唯一的物種了。物體物件上會存在著框架物件,框架物件上儲存著形狀物件,然後物體帶著框架和形狀在世界中運動。Box2D中的物體總是剛體(rigid body)。這也就是說同一剛體上的兩個框架,永遠不會相對移動。

框架物件持有著用於碰撞檢測的幾何形狀與用於物理模擬的密度(density)等屬性。物體只是一個存在的軀殼。通常引擎要從它的框架中獲得質量屬性。當物體構建之後,開發者也可以改變它的質量屬性。通常開發者會儲存所有建立物體的指標,這樣在遊戲中就能查詢到物體的位置,用於更新其對應遊戲元素的位置。另外在不需要它們的時候,也可以使用這些指標去摧毀它們。

位置和角度(position and Angle)

位置和角度,對於一個物體來說算是最基本的屬性。這也就是說存在於物理世界的物體都不會缺少這兩個屬性。如果開發者在構建物體的時候,沒有設定這兩個屬性的數值,則引擎會提供初始化預設引數。在初始化直接傳遞位置和角度引數,這比在常見物體後再移動到某個位置或者角度更高效。

注意:不要在原點建立物體後再移動它,。如果你再原點上同事建立了幾個物體,效能會很差。

物體上主要有兩個屬性是引擎需要的:

(1)第一個是物體的原點。框架和關節都是相對於原點而依附到物體上面的。這也就是框架和關節將會使用物體自身的座標系來進行定位麼人不是世界座標系。

(2)第二個是物體的質心。質心由形狀的質量分佈決定。因為引擎中的物體是剛體,所以其質心處在均勻的位置。但是開發者可以顯式的呼叫函式b2MassData來設定。

當開發者構造物體定義的時候,可能並不知道質心在哪裡。雖然我們可以指定物體的原點,也可能會以弧度指定物體的角度,但是這都不代表質心。只有改變了物體的質量屬性也就是密度,那麼質心才會隨之移動。在質心改變的時候,其原點以及物體上的形狀和關節都不會改變,同樣物體的角度也不受質心位置的影響。

在建立物體時,開發者可以在物體定義物件中設定位置和角度的初始化數值:

bodyDef.position.Set(0.0f,2.0f);//body的原點

bodyDef.angle = 0.25f *b2_pi;//弧度制下的body的角

當然,在物理引擎運轉的過程中,物體的位置和角度也會隨時改變。開發者可以通過物體類中的函式來改變:

void SetTransform(const b2Vec2& position,float32 angle);

阻尼(Damping)

阻尼是一種非常專業的物理概念,它是一種用於表示減少物體在世界中的速度的數值。阻尼與摩擦有所不同,摩擦僅在物體有接觸的時候才會發生,而阻尼卻時時刻刻阻礙著物體運動。可以把它理解為真實世界中的空氣阻力。很明顯它與摩擦屬性之間兩者是不能互相替換的,往往這兩個效果需要同時作用於物體。

阻尼引數的數值範圍可以是從零到無窮大。零表示沒有阻尼,無窮大表示滿阻尼。通常來說,阻尼的值應該在0-0.1之間,畢竟阻力太大,物體會很難前行。

注意:建議不要輕易使用線性阻尼,除非明確知道會產生怎樣的效果,因為它會使物體看起來有點漂浮。

幾乎所有的物體屬性都可以在物體定義物件中賦予初值。下面程式碼是設定物體的線速度阻尼和角速度阻尼:

bodyDef,linearDamping = 0.0f;

bodyDef.angularDamping = 0.01f;

由於阻尼時時刻刻都會影響物體的運動,出於對穩定性和效能的考慮,在其值較小的時候阻尼效應幾乎不依賴時間步,這是為了減少運算效能的損失。當其值較大時阻尼效應應隨著時間步而改變。

休眠引數(Sleep Parameters)

模擬物體的成本是高昂的,如果物體越少,那模擬的效果就會更好。當物體停止了運動時,我們就要停止模擬它。當Box2D確定一個物體(或一組物體)已停止移動時,物體就會進入休眠狀態。休眠物體只消耗很小的CPU開銷。如果一個醒著的物體接觸到一個休眠中的物體,那麼休眠中的物體就會醒過來。當物體的關節或者觸點被摧毀的時候,他們同樣會醒過來。當然也可以手動的喚醒物體,通過物體定義,你可以指定一個物體是否可以休眠,或者建立一個休眠的物體:

bodyDef.allowSleep = true;

bodyDef.awake = true;

固定旋轉(Fixed Rotation)

此屬性也是一個與旋轉有關的屬性,它可以讓一個剛體具有固定的旋轉角,但是它在任何情況下都不會旋轉。如果虛妄使用固定角度的物體,可以通過設定fixedRotation來達到目的

bodyDef.fixedRotation = true;


當其值為真,則物體的轉動慣量被設定為0,這也就是說物體會保持初始化的角度,而不會發生旋轉。

子彈(Bullets)

子彈也是物體中的一個很特別的屬性。其實也好理解,就是將物體變成子彈一樣的屬性。而不是變成子彈!子彈有什麼屬性?子彈通常指一類速度很快而尺寸很小的物體。此類物體有一個特點,就是容易擊穿其他物體。

遊戲中的渲染世界,尤其自身的繪製週期。渲染引擎通常會以一定幀率繪製一系列圖片。這說明渲染的過程,並不是一個連續的過程。這就是所謂的離散模擬。物理模擬中的世界同樣採用了離散模擬的方法。物理世界會按照時間步的節奏來運轉。如果在一個時間步內,速度快的剛體可能移動較大距離,恰好此物體擁有一個較小的體積,引擎如果沒有處理好的話,那麼可能看到一些物體錯誤的穿過了彼此。開發者並不希望此種情況的發生,因此有了子彈的特殊型別。這種現象在遊戲領域中被稱為隧穿效應。

既然發現了問題,就要找到應對的方法。在預設情況下,引擎會通過連續的碰撞檢測(CCD)來防止動態物體穿越靜態物體。這是通過掃描形狀從舊位置的過程來完成的。引擎會查詢掃描中新的碰撞物件,併為這些碰撞計算碰撞時間(TOI)。物體會先被移動到它們的第一個TOI,然後一直模擬到原時間步的結束。此方法應用在動態物體和靜態物體之間。

一般情況下,動態物體之間不會應用連續碰撞檢測的方法,因為此方法需要更多的數學運算。不過在一些遊戲環境中,開發者需要在動態物體上也使用連續碰撞檢測。比如《憤怒的小鳥》,開發者需要一個不會穿越其他物體的效果,如果沒有連續碰撞檢測,小鳥就可能會穿牆而過。

注意:連續碰撞檢測也不是完美的演算法,兩個快速移動的物體之間也會出現穿越的問題。

考慮到上面的問題,Box2D引擎中為高速移動的物體提供了一個特別的屬性。那就是將其標誌為子彈(bullet)。具備了子彈屬性的物件,在與動態和靜態物體碰撞時都會直行連續碰撞檢測(CCD)。因此,讀者可以按照遊戲的設計需要來決定哪些物體具備子彈的特點。如果決定一個物體應該按照子彈去處理,則可以在物體定義中設定。

bodyDef.bullet = true;

注意:子彈標記只可用在動態物體上

活動狀態(Activation)

活動狀態就是用來表示物體的當前狀態的,如果一個物體處於活動狀態,那麼它就會參與引擎的物理模擬和碰撞模擬。如果為非活動狀態,那麼它不會參與引擎的物理模擬和碰撞檢測。

注意:非活動狀態和休眠狀態不一樣,非活動狀態只能通過開發者啟用,而休眠狀態值需要受到碰撞就啟用

在實際的程式碼中,讀者可以建立一個非活動的物體,之後再遊戲需要的情況下,再來啟用它。這樣做可以減少不必要的計算。程式碼如下:

bodyDef.active = true;


另外,一個處於非活動狀態的物體,將會完全不參與物理模擬和碰撞檢測,與它連線的關節也不會模擬,所以設定非活動狀態一定要注意!

使用者資料(User Data)

也就是存有物體屬性的使用者資料,它會將物體和遊戲關聯起來,開發者可以用一個物體物件來對應一個遊戲元素。事實上所有物體的使用者資料都應該指向相同的物件型別:

b2BodyDef bodyDef;

bodyDef,userData = &myActor;

相關推薦

cocos2dx物理引擎碰撞檢測()物體Bodies

前面已經講到形狀和框架的含義,它們分別是用來進行碰撞檢測和物理模擬的物件。到現在我們建立的物理世界當中,還未存在任何的物體。因此接下來的內容就介紹物理世界的主角:物體(Body)。它是構成世界的主要因素,因為不僅框架,形狀會依附於物體,就連後面介紹的關節也是要繫結在物體之上

cocos2dx物理引擎碰撞檢測(五)框架Fixtures

框架Fixture是動態模組中的一個重要的概念,它和形狀Shape將來都是要附加到物體Body上。在一開始介紹Box2D引擎時,就曾說過物理引擎可以被看作是兩部分:碰撞檢測和物理模擬。形狀Shape是用來進行碰撞檢測的,那麼框架Fixture就是用來進行物理模擬的。在介紹框

cocos2dx物理引擎碰撞檢測(四)形狀Shapes

前面讓大家瞭解了物理世界,下面將為大家介紹物理世界中的物體。 形狀Shape描述了可相互碰撞的幾何物件的外形,它通常會是一個幾何圖形,這與包圍盒的概念非常相似。在引擎當中,形狀可以作為一個單獨的物件,就算不進行物理模擬,也可獨立使用,開發者可以在形狀Shape上執行一些函式

cocos2dx物理引擎碰撞檢測(三)

上文中講到了如何遍歷物理世界,但是大家想想,我們訪問了世界容器中的每一個物體,只是為了找到一個匹配的物件,這是一個非常耗時的操作,如果遊戲當中存在一百個物件,此時開發者只想找到一個發生碰撞的物件,難道就必須要將一百個物件都訪問一遍嗎?所以Box2D引擎提供了一種訪問物件的方

實例介紹Cocos2d-x中Box2D物理引擎碰撞檢測

函數實現 pda creates pty blank oid rtu and 重構 在Box2D中碰撞事件通過實現b2ContactListener類函數實現,b2ContactListener是Box2D提供的抽象類,它的抽象函數:virtual void BeginC

Unity3D物理引擎碰撞

本小節主要是Unity物理引擎,剛體碰撞方面的散記。 Character Controller的一些特性: 本身不受physics影響,需要接受外力作用時,使用onCharacterColliderHit(). Skin width:最好設定為radius的10%,防止

例項介紹Cocos2d-x中Box2D物理引擎碰撞檢測

在Box2D中碰撞事件通過實現b2ContactListener類函式實現,b2ContactListener是Box2D提供的抽象類,它的抽象函式:virtual void BeginContact(b2Contact* contact)。兩個物體開始接觸時會響應,但只調用

利用jsplumb碰撞檢測自動生成流程圖

for ans ont != 500px cat clone tran tex 使用jsplumb構建流程圖模型時,有一個需求要求,選項可以從選項表中拖拽到指定容器,並且兩個選項要接觸到的時候才能連接起來,不接觸不能連接。效果圖如下 略醜~ 因為這裏用到了拖拽,拖放功

【JavaScript】實現元素拖拽碰撞檢測

function drag() { var src1 = document.getElementById("src-1"); var src2 = document.getElementById("src-2"); var src3 =

unity物理引擎--Collider(碰撞器)

碰撞器可以實現的功能:字面意思,讓兩個物體碰撞(即物體接觸不會穿過物體)並可以產生一個碰撞事件 一般來說建立一個物體時系統會自動匹配相應的Collider(碰撞器) 但只是對系統自帶的物體來說,下面說一下如何新增/修改碰撞器       u

Unity觸發檢測碰撞檢測

void OnCollisionEnter(Collision col) { Debug.Log("開始碰撞" + col.collider.gameObject.name); } void OnCollisionStay

cocos2dx 3.x 物理引擎接觸檢測掩碼、碰撞掩碼類別掩碼問題解析

言簡意賅,物體的類別掩碼CategoryBitMask和物體的接觸測試掩碼ContactTestBitmask邏輯“與”運算結果非零,則觸發EventListenerPhysicsContact事件監聽器,物體的類別掩碼CategoryBitMask和物體

物理引擎中不規則物體碰撞檢測

在運用物理引擎的時候,經常回出現這種情況,不規則物體的碰撞檢測無法更加精確的測量,那麼,小杰今天就帶您一起解決這個問題!!! 首先下載一個windows下面的軟體 名稱是:PhysicsEditor ,這個軟體可以幫助你設計不規則的圖形。軟體的使用方法在這裡不具體講解了,說

cocos2dx 精靈的碰撞檢測消滅(3)

在上一篇的基礎上增加了一點內容,必要的註釋都寫在程式碼裡了,,就直接貼程式碼吧,我也懶得寫詳細的過程。 HelloWorldSence.h #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #in

bullet物理引擎與OpenGL結合 匯入3D模型進行碰撞檢測 以及畫三角網格的坑

原文作者:aircraft 原文連結:https://www.cnblogs.com/DOMLX/p/11681069.html         一.初始化世界以及模型 /// 衝突配置包含記憶體的預設設定,衝突設定。高階使用者可以建立自己的配置。 btDefault

chipmunk 物理引擎的基本概念基本用法

num 碰撞回調 2.0 ddb mat sha print 單獨 得出 chipmunk是一個開源2D物理引擎, 項目主頁:http://code.google.com/p/chipmunk-physics/ 工作需要研究了一下,這個引擎的資料還是不多,我閱讀了

Cocos2d-x 3.0中 物理碰撞檢測中onContactBegin回調函數不響應問題

track 後來 which compare mar details egl def trac 好吧,事實上這篇也是暫時冒出來的,近期朋友要做個物理遊戲,曾經做物理還是用box2d,呃。確實要花些功夫才幹搞懂當中的精髓,可是聽講這套引擎又一次封裝了一次。要easy非

canvas遊戲動畫中的碰撞檢測

底部 bsp rect circle 進行 eight nbsp odi word 碰撞檢測關鍵步驟 碰撞檢測需要處理經歷下面兩個關鍵的步驟: 計算判斷兩個物體是否發生碰撞 發生碰撞後,兩個物體的狀態和動畫效果的處理 計算碰撞 只要兩個物體相互接觸,它們就會發生碰撞

Unity3D 網格碰撞器Mesh Collider之間原型碰撞器(Box Collider等)的碰撞檢測

There are some limitations when using the Mesh Collider. Usually, two Mesh Colliders cannot collide with each other. All Mesh Colliders can co

unity碰撞檢測觸發器的方法函式

碰撞檢測涉及三個函式: 當與物體碰撞的一瞬間:OnCollisionEnter(Collision  collision),collisionInfo是撞到的物體的碰撞資訊; 當在與物體持續碰撞接觸期間:OnCollisionStay(Collision collisio