by AlexQ (email alexq_andr@163.com)
工程托管在此:GitHub

本文目的是為之后介紹libGDX中使用Box2D實(shí)現(xiàn)一個(gè)碰撞效果做技術(shù)鋪墊,關(guān)于Box2D的諸多概念不會(huì)一一涉及、深入講解,望能見諒,不過好在Box2D學(xué)習(xí)資料頗多,您可以到網(wǎng)上免費(fèi)獲得很多幫助。
導(dǎo)語(yǔ)
- What's Box2D
- About Box2D
- Core
- 推薦
注意:我們的Box2D事例代碼全部基于libGDX封裝的接口和類
聲明:本文中大量引用了《Box2D 物理游戲編程 初學(xué)者指南》作者 陳文登 中原文,在此特別聲明,
也推薦大家如果入門學(xué)習(xí)的話這本書很不錯(cuò),使我受益匪淺。
What's Box2D
Box2D is an open source C++ engine for simulating rigid bodies in 2D.
Box2D官網(wǎng)
About Box2D
Box2D被很多大型的游戲開發(fā)引擎所使用:cocos2D、HTML5、Starling、Unity3D、libGDX...
Box2D核心解決的問題是:"Box2D 集成了大量的物理力學(xué)和運(yùn)動(dòng)學(xué)的計(jì)算,并將物理模擬過程封裝到類對(duì)象中,將對(duì)物體的操作,以簡(jiǎn)單友好的接口提供給開發(fā)者。"例如:加速、減速、拋物線運(yùn)動(dòng)、萬(wàn)有引力、碰撞反彈等等各種真實(shí)的物理運(yùn)動(dòng)
Core
關(guān)于Box2D概念大致包涵:Box2D世界概念、剛體以及剛體屬性、剛體的操作、碰撞自處理、關(guān)節(jié)、向量運(yùn)算等等,我們?cè)谌腴T時(shí)簡(jiǎn)要的抽取核心中的核心介紹一下
1.Box2D世界
重力世界
創(chuàng)建世界
Debug視圖
2.剛體
剛體概念
形狀
3.剛體屬性
1.Box2D世界
1).重力世界
重力,簡(jiǎn)單的講,就是使物體自然下落的力,Box2D 用 Vector2 向量類來模擬作用力。Vector2 是 “Box2D Vector2D”的縮寫,表示二維空間中的一個(gè)向量,Vector2 類的構(gòu)造函數(shù)中只有 x 和 y 兩個(gè)
參數(shù),分別表示 x 軸和 y 軸方向上的分量。
new Vector2(x, y)
對(duì)于C++,重力方向參考如下:

因?yàn)橹亓κ谴怪毕蛳碌?在水平方向沒有任何力,所以 x 設(shè)置為 0,這個(gè)不難理解。至于y的參數(shù)值-9.8,實(shí)際上,這里的y指的是重力加速度,我們讀高中時(shí)都學(xué)過,在沒有任何阻力影響的情況, 理論的重力加速度是 9.8m/s2(米每平方秒)。 Box2D 中的坐標(biāo)系統(tǒng)的單位是米(m) 這點(diǎn)很重要 這點(diǎn)很重要 這點(diǎn)很重要
實(shí)際上 Box2D 中的重力 gravity 可以設(shè)置為任意方向的任意大小,來模擬不同朝向的“重力”。甚至 可以設(shè)置為 new b2Vec2(0,0),模擬出一個(gè)類似太空的完全失重狀態(tài),這也是利用 Box 2 開發(fā)俯視 類游戲時(shí),經(jīng)常使用的設(shè)置。
2).創(chuàng)建世界
“世界”在 Box2D 中用 World 類來表示,World 類的構(gòu)造函數(shù)中有兩個(gè)參數(shù)。一個(gè)是 Vector2 類型的 gravity,也就是上面我們講的重力;第二個(gè)是一個(gè)叫做 doSleep 布爾值參數(shù),表示 Box2D 引擎是否將靜止不動(dòng)的剛體設(shè)置為睡眠狀態(tài)
World myworld = new World(new Vector2(x, y), true);
任何的運(yùn)動(dòng)物體,因?yàn)槟Σ亮?、能量轉(zhuǎn)換等因素,最終都會(huì)慢慢停止運(yùn)動(dòng)。Box2D 中的剛體也是一 樣,正常情況下,Box2D 會(huì)遍歷世界中的所有剛體,通過復(fù)雜的公式計(jì)算,模擬物理運(yùn)動(dòng)。但是對(duì)于靜止不動(dòng)的剛體來說,這時(shí)的物理運(yùn)動(dòng)模擬計(jì)算是沒有必要的。當(dāng)參數(shù) doSleep 為 true 時(shí),Box2D 會(huì)通過將靜止的剛體標(biāo)記為睡眠狀態(tài),在遍歷時(shí)直接跳過,不進(jìn)行運(yùn)動(dòng)模擬計(jì)算,這樣就提升了 Box2D 的運(yùn)算效率,節(jié)省 CPU 開支。
3).Debug視圖-開啟Box2D模擬
簡(jiǎn)單說來,僅僅創(chuàng)建世界、創(chuàng)建我們之后提到的剛體后,運(yùn)行程序你是看不到任何東西的,Box2D是一個(gè)模擬真實(shí)世界的計(jì)算引擎系統(tǒng),他并不負(fù)責(zé)繪制貼圖工作,那么我們?cè)跊]有利用Box2D運(yùn)算結(jié)果進(jìn)行貼圖的情況下,如何能夠看到我們模擬的世界或物體呢,他給我提供了一套專門用來Debug Renderer的方式,這就是我們所說的Debug視圖。
// Create debugrender object
Box2DDebugRenderer m_debugRenderer = new Box2DDebugRenderer();
...
//render function do this
m_debugRenderer.render(world, camera.combined);
使用Debug視圖后,如圖中黑色背景的部分,你會(huì)看到世界中創(chuàng)建的剛體以有顏色的線條勾勒出邊緣來提示你

2.剛體
如果說 World 類是 Box2D 引擎中的第一基本要素,那 第二肯定非 Body 類莫屬了。Body 就是我們常說的剛體,”剛體”這個(gè)名詞是從 solid body 直譯 過來的,用來在 Box2D 中仿真各種物體?!稇嵟男▲B》中的小鳥,《割繩子》里的糖果等等都是 用剛體模擬出來的效果。

1).剛體概念
A rigid body(一個(gè)固態(tài)的物體)
Body 是 Box2D 的核心類,是學(xué)習(xí) Box2D 的基礎(chǔ),也是重中之重。Body 用來模擬現(xiàn)實(shí)物理世界中的所有物體。Box2D 中的任何碰撞、反彈、運(yùn)動(dòng)軌跡等各種物理現(xiàn)象模擬和數(shù)據(jù)計(jì)算都是基于剛體實(shí)現(xiàn)的,所以剛體 b2Body 所包含的信息有很多,如物體的坐標(biāo)、角度、受力大小、速度、質(zhì)量等大量的信息。
2).創(chuàng)建剛體
BodyDef BallBodydef = new BodyDef();
BallBodydef.type = BodyDef.BodyType.DynamicBody;
Body BallBody = world.createBody(BallBodydef);
BallBody.setUserData(new BallInfo());
BallBody.setFixedRotation(false);
CircleShape shape = new CircleShape();
shape.setRadius(1f);
FixtureDef BallFixtureDef = new FixtureDef();
BallFixtureDef.shape = shape;
BallFixtureDef.density = xxx;
BallFixtureDef.friction = yyy;
BallFixtureDef.restitution = zzz;
BallBody.createFixture(BallFixtureDef);
shape.dispose();
三大核心概念:
- BodyDef:要?jiǎng)?chuàng)建的剛體信息定義
- Body:要?jiǎng)?chuàng)建的剛體
- FixtureDef :要?jiǎng)?chuàng)建的剛體信息定義
BodyDef 和 FixtureDef 所對(duì)應(yīng)的屬性具體如下表,很好的通過各自的屬性詮釋了自身的意義:

3).形狀
sharp是另外一個(gè)非常重要的因素,FixtureDef 對(duì)象的 shape 屬性。實(shí)現(xiàn)了剛體的具體形狀,Box2D 將基于這個(gè)形狀進(jìn)行精確的物理碰撞模擬。兩類形狀:圓形、矩形,我們只舉圓形的例子,矩形請(qǐng)無(wú)師自通吧。
- 圓形: 在 Box2D 中用 CircleShape 類表示,這里的圓形是一個(gè)”標(biāo)準(zhǔn)圓”,也就是說像橢圓形、扇形 或半圓形這類”非標(biāo)準(zhǔn)圓”是無(wú)法用 CircleShape 類來創(chuàng)建的。
CircleShape shape = new CircleShape();
shape.setRadius(xxx);
3.剛體屬性 BodyDef
BodyDef 類包含的剛體屬性有10多種,包括剛體類型、線性速度、角速度等等,主要是剛體運(yùn) 動(dòng)和狀態(tài)相關(guān)的屬性,這部分內(nèi)容請(qǐng)參考推薦書目中或者官方文檔,詳細(xì)了解,我們只羅列一下大只的屬性以及用途

BodyDef.type
BodyDef一共有三種類型,分別是:
- staticBody 靜態(tài)剛體,指靜止不動(dòng),碰撞后不進(jìn)行反彈等運(yùn)動(dòng)模擬的剛體,此剛體不受任何外力的影響,不能調(diào)節(jié)速度,通常用來做物理游戲里面的地面、平臺(tái)等;
- KinematicBody 可動(dòng)剛體, 這類剛體和靜態(tài)剛體類似,碰撞后同樣不進(jìn)行反彈等運(yùn)動(dòng)模擬,但是他是可以動(dòng)的,可以主動(dòng)給他添加初速度等,讓他動(dòng)起來,例如游戲中上下升降的電梯;
- DynamicBody 動(dòng)態(tài)剛體,這是最常見的類型,可以運(yùn)動(dòng),在碰撞后按照物理定律做出反彈、變相等響應(yīng)的剛體。;
到此為止我們告一段落,其實(shí)Box2D還有很多概念等待你學(xué)習(xí),如果你是用它來真正做一個(gè)類似憤怒小鳥的游戲,那么關(guān)節(jié)、碰撞處理的細(xì)節(jié)都必須要清洗妙了的理解、熟練的應(yīng)用才可以。

4.推薦
1.推薦書目

作者: 陳文登
出版社: 科學(xué)出版社
出版年: 2015-3-16
頁(yè)數(shù): 328
定價(jià): 78
裝幀: 平裝
ISBN: 9787030434340