SceneKit框架詳細解析(四) —— 基于SceneKit的簡單游戲示例的實現(xiàn)(三)

版本記錄

版本號 時間
V1.0 2018.10.20 星期六

前言

SceneKit使用高級場景描述創(chuàng)建3D游戲并將3D內容添加到應用程序怨愤。 輕松添加動畫,物理模擬,粒子效果和逼真的基于物理性的渲染睹欲。接下來這幾篇我們就詳細的解析一下這個框架灼舍。感興趣的看下面幾篇文章吼和。
1. SceneKit框架詳細解析(一) —— 基本概覽(一)
2. SceneKit框架詳細解析(二) —— 基于SceneKit的簡單游戲示例的實現(xiàn)(一)
3. SceneKit框架詳細解析(三) —— 基于SceneKit的簡單游戲示例的實現(xiàn)(二)

開始

在這部分中,您將學習如何通過Scene Kit物理的強大功能使幾何體移動骑素。

我們開始吧炫乓!

在本教程中,您將使用SceneKit的物理引擎為您的游戲添加物理献丑。

SceneKit的物理引擎功能強大末捣,易于使用。 您只需告訴SceneKit您想要應用物理的對象创橄,引擎將從該點接管箩做,模擬重力和碰撞等事物。

在深入將物理學集成到游戲中之前妥畏,您首先需要為項目添加一些game utilities邦邦。


Introducing the Game Utilities - 介紹游戲工具

game utilities是專門為您創(chuàng)建的安吁。 它們包括輔助方法,可以處理游戲中的復雜位燃辖。 這讓你專注于游戲玩法鬼店,而不是那些討厭的比特。

在這里加了一些游戲相關的工具黔龟,就不細說了妇智,后面用到會詳細說明。

1. Adding the Game Utilities - 添加游戲工具

要添加游戲實用程序捌锭,只需將GameUtils文件夾拖放到GeometryFighter組文件夾下的項目中:

將所有設置保留為默認值俘陷,然后單擊Finish

這會將整個GameUtils文件夾作為一個組導入到您的項目中。 展開此組文件夾观谦,快速查看一些幫助程序方法拉盾。 如果某些代碼對您沒有意義,請不要太擔心豁状。


Physics - 物理

是時候快速狀態(tài)檢查游戲的當前狀態(tài)了捉偏。構建并運行游戲;一個很酷的隨機幾何物體像某種黑暗魔法一樣在空氣中產(chǎn)生泻红。這可能現(xiàn)在看起來不太多夭禽,但很快就會有所改善!

剛剛產(chǎn)生的物體只是掛在空曠的空間里并沒有做太多谊路。當然讹躯,你可以圍繞它旋轉相機并放大和縮小,但也就是只能這樣缠劝。這不是一個有趣的游戲潮梯。為了提高興奮程度,如果物體至少移動一點惨恭,那就太好了秉馏。

現(xiàn)在,你可以走很長的路脱羡,并隨著時間的推移操縱對象的位置和旋轉萝究,以便旋轉和移動。您很快就會意識到雖然可以以這種方式為對象設置動畫锉罐,但它需要大量的編碼工作 - 尤其是當您添加其他功能(如真實碰撞和對象之間的交互)時帆竹。

值得慶幸的是,Apple的開發(fā)人員已經(jīng)考慮過這一點氓鄙;為此馆揉,他們將一個非常強大的3D物理引擎集成到SceneKit中。要使用這個內置的物理引擎抖拦,您只需要讓引擎知道您的對象升酣。

以將幾何信息附加到節(jié)點的方式相同舷暮,可以將physics body附加到節(jié)點。物理主體描述了節(jié)點的所有物理屬性噩茄,包括形狀下面,質量,摩擦绩聘,阻尼和恢復等內容沥割。物理引擎在模擬對象的真實物理交互時會考慮所有這些信息。這包括重力凿菩,摩擦和物理世界中其他物體碰撞等事物机杜。

下一節(jié)將詳細介紹物理機構的一些重要特征。

1. Physics Body Types - 物理體類型

創(chuàng)建物理主體時必須指定的關鍵屬性之一是其類型(type)衅谷。物理體類型定義了物體如何與模擬中的力和其他物體相互作用椒拗。

SceneKit中使用了三種類型:

  • 靜態(tài)(Static)物體不會移動:當其他物體可能與這些物體碰撞時,靜態(tài)物體本身不受模擬中任何力和碰撞的影響获黔。您可以將此類型用于墻壁和巨大的固定巨石等物體蚀苛。
  • 動態(tài)(Dynamic)物體由物理引擎自動移動以響應力和碰撞。您可以將此類型用于可移動椅子玷氏,桌子和杯子等物品堵未。
  • 物理引擎不會自動移動運動(Kinematic)物體以響應力和碰撞。換句話說盏触,如果運動物體與動態(tài)(dynamic)物體碰撞渗蟹,動態(tài)物體將會移動,但運動物體不會移動赞辩。但是拙徽,您可以在代碼中手動移動運動體。您可以將此類型用于手動控制的內容诗宣,例如移動電梯或可以打開和關閉的門。

2. Physics Shapes - 物理形狀

除了物體的類型之外想诅,在創(chuàng)建物理主體時必須指定的另一個導入屬性是其形狀(shape)召庞。 物理形狀定義物理引擎在碰撞檢測期間使用的3D形狀。 雖然幾何定義了節(jié)點的視覺效果来破,但物理主體定義了節(jié)點如何與物理模擬中的其他對象進行交互篮灼。

您可以使形狀(shape)與視覺幾何形狀完全相同,但這通常比您需要的計算成本更高(因此導致您的游戲運行速度變慢)徘禁。 相反诅诱,您通常應該使用幾何體的簡化版本,例如簡單的邊界框送朱,球體或其中一個提供的原始形狀娘荡,大致匹配節(jié)點的可見外觀干旁,如下所示:

3. Adding Physics - 添加物理

現(xiàn)在你已經(jīng)學會了物理背后的理論,現(xiàn)在是時候開始使用這些概念來改變游戲中的事物了炮沐。

在SceneKit中争群,所有物理實體都是SCNPhysicsBody對象。 創(chuàng)建物理主體后大年,可以將其分配給SCNNode實例的physicsBody屬性换薄。 一旦將物理主體分配給適當?shù)墓?jié)點,物理引擎就可以為您模擬物理翔试。 就這么簡單轻要!

打開GameViewController.swift并在spawnShape()中創(chuàng)建geometryNode的代碼行之后添加以下內容:

geometryNode.physicsBody =
  SCNPhysicsBody(type: .dynamic, shape: nil)

這行代碼創(chuàng)建了SCNPhysicsBody的新實例,并將其分配給geometryNodephysicsBody屬性垦缅。 創(chuàng)建物理實體時冲泥,可以指定實體的類型和形狀。 如果為物理形狀傳遞nil失都,SceneKit將根據(jù)節(jié)點的可視幾何體自動生成形狀柏蘑。

如果要向物理形狀添加更多細節(jié),可以創(chuàng)建SCNPhysicsShape并將其用于形狀而不是傳入nil粹庞。

構建并運行您的游戲; 一個隨機的形狀產(chǎn)生進入場景咳焚,然后以死鳥的所有優(yōu)雅的方式從空中掉落,掉出視線:

您甚至可以平移相機以觀察物體庞溜。 你在這里看到的是重力作用于物體的影響革半。 SceneKit中的場景默認情況下重力打開。 現(xiàn)在生成的對象具有物理主體流码,物理模擬將模擬力(例如重力)應用于對象又官。


Forces - 力

想一想現(xiàn)實生活中的物體:做一些移動的東西 - 比如桌子上的勺子 - 你必須對它施加某種類型的物理力。

SceneKit物理引擎在模擬真實物理方面做得相當不錯漫试,所以就像你在現(xiàn)實生活中使用力來移動物體一樣六敬,你需要在你的物理體上施加一個力來移動物體。

當你將力施加到一個物理體驾荣,你用applyForce(direction: at: asImpulse:)并傳遞一個SCNVector3實例外构。可以獲得你要施加力時候的力和位置播掷,您施加的力會影響物理體的線性加速度和角加速度审编。

沖擊(impulse)僅將力施加到物理體上,例如當你踢球時歧匈。物理模擬中的每一步都應用非沖擊力垒酬。 SceneKit將在對象上添加所有施加的力,并根據(jù)這些力的最終結果加速物理體。這可以模擬類似于助推火箭的東西勘究,其中力是連續(xù)的矮湘。

之前,您了解到力是具有x乱顾,y和z分量的向量板祝。但是,這是什么意思走净?看看下圖:

力具有大小和方向券时,因此矢量確定每個軸的力的大小。 在上面的示例中伏伯,應用具有(x:0橘洞,y:10,z:0)向量的力可以使用垂直力向上移動主體说搅。

要應用水平力炸枣,您只能使用(x:10,y:0弄唧,z:0)的向量指定x軸上的力的大小适肠。 要向左移動而不是向右移動,您將在x軸上施加負的力大小候引。 當您將各種矢量組合在一起時(x:10侯养,y:10,z:0)澄干,您可以準確控制身體的移動方式 - 在這種情況下逛揩,對角線。

力也可以應用于物理體的特定位置以產(chǎn)生不同的運動:

同樣麸俘,它有助于思考現(xiàn)實生活中的例子辩稽。 如果你前面有一個擋塊并推動它,擋塊會根據(jù)你施加推動的位置而有所不同从媚。 將相同的力施加到身體質心的左側或右側逞泄,例如,在(x:1拜效,y:0炭懊,z:0)處將使其旋轉。在(x:0拂檩,y:0,z:0)處直接施加與質心一致的力將不會產(chǎn)生旋轉嘲碧。

1. Applying Force - 施力

卷起你的袖子 - 是時候施加一些力量了稻励!

spawnShape()中為geometryNode創(chuàng)建物理體的行之后添加以下代碼:

// 1
let randomX = Float.random(min: -2, max: 2)
let randomY = Float.random(min: 10, max: 18)
// 2
let force = SCNVector3(x: randomX, y: randomY , z: 0)
// 3
let position = SCNVector3(x: 0.05, y: 0.05, z: 0.05)
// 4
geometryNode.physicsBody?.applyForce(force,
  at: position, asImpulse: true)

下面進行詳細說明:

  • 1) 這將創(chuàng)建兩個隨機浮點值,表示力的x和y分量。 它使用您在本教程前面添加的實用程序的Float擴展望抽。
  • 2) 接下來,使用這些隨機組件創(chuàng)建一個向量來表示此力。
  • 3) 這將創(chuàng)建另一個向量程癌,表示力將應用到的位置璧诵。 該位置稍微偏離中心,以便在物體上產(chǎn)生旋轉辑奈。
  • 4) 最后苛茂,使用所有這些組件,使用applyForce(direction:at:asImpulse :)將力應用于geometryNode的物理體鸠窗。

構建并運行妓羊;當物體憑空產(chǎn)生時,一些神奇的力量將它踢向空中稍计,而不是像死鳥一樣掉落:

當重力作用時躁绸,物體最終會落下。


Torque - 扭力

扭矩是另一種可以使用applyTorque(torque: asImpulse:)應用于物體的旋轉力臣嚣。 扭矩僅影響物理體的角動量(自旋)净刮,而不影響線性動量(x,y硅则,z)淹父。 施加扭矩導致物體圍繞其質心旋轉。

要了解扭矩如何影響物理機構抢埋,請查看下圖:

應用扭矩力時弹灭,使用SCNVector4指定四分量矢量,而不是像使用力一樣使用三分量矢量揪垄。 x穷吮,y和z分量確定旋轉軸,而w分量確定旋轉角度饥努,即扭矩的大小捡鱼。
就像使用applyForce(direction:at:asImpulse :)一樣,您可以選擇是否將扭矩應用為沖擊酷愧,這會影響物理引擎處理矢量的方式驾诈。

如果扭矩是沖擊,則方向矢量被視為角動量的瞬時變化溶浴。想想用手指旋轉籃球乍迄;為了保持球的旋轉,你必須用你的手快速揮動球的一側士败,每次輕彈都會產(chǎn)生一個沖擊闯两,瞬間增加球的角動量褥伴。

當扭矩不作為沖擊施加時,它在每個物理模擬步驟之后應用漾狼。 SceneKit將對所有施加的力和扭矩求和重慢,并根據(jù)這些力的凈效應加速物理體的角力⊙吩辏可以把它想象成一個圍繞自己的軸以恒定速度旋轉的行星似踱。

注意:SceneKit物理模擬使用國際單位系統(tǒng)(SI)進行測量:質量單位的公斤數(shù),力單位的牛頓稽煤,脈沖(impulse)單位的牛頓秒和扭矩單位的牛頓米核芽。


Adding Flair - 添加Flair

既然你已經(jīng)移動了幾何物體,你可能已經(jīng)注意到它在屏幕中間的空氣中產(chǎn)生念脯,這看起來有點尷尬狞洋。 為了解決這個問題,你可以將相機在y軸上移動一點绿店,這樣物體就會在屏幕外產(chǎn)生吉懊。

1. Positioning the Camera - 定位相機

要向上移動攝像機位置,請使用以下內容替換在setupCamera()中設置攝像機位置的行:

cameraNode.position = SCNVector3(x: 0, y: 5, z: 10)

構建并運行假勿,您將看到該對象似乎在屏幕外生成借嗽!

2. Adding some Color - 添加一些顏色

最后,您可以為隨機生成的形狀添加一些變化转培。

spawnShape()中添加以下幾行恶导,在您隨機創(chuàng)建geometry的位置之后,但在創(chuàng)建geometryNode之前:

geometry.materials.first?.diffuse.contents = UIColor.random()

要為隨機對象著色浸须,可以修改geometry上的materials惨寿;此行獲取幾何體的第一個可用材質,并將diffuse屬性的內容設置為隨機UIColor删窒。 UIColor上的random()方法是另一個被定義為game utilities內部擴展的助手裂垦。

注意:這里需要注意的是,您可以為漫反射(diffuse )屬性的內容指定UIColor肌索,以便更改對象的顏色蕉拢。

最后,構建并運行游戲以查看顏色漂亮的對象:

后記

本篇主要講述了基于SceneKit的簡單游戲示例的實現(xiàn)诚亚,感興趣的給個贊或者關注~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末晕换,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子站宗,更是在濱河造成了極大的恐慌闸准,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件梢灭,死亡現(xiàn)場離奇詭異夷家,居然都是意外死亡腕唧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門瘾英,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人颂暇,你說我怎么就攤上這事缺谴。” “怎么了耳鸯?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵湿蛔,是天一觀的道長。 經(jīng)常有香客問我县爬,道長阳啥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任财喳,我火速辦了婚禮察迟,結果婚禮上,老公的妹妹穿的比我還像新娘耳高。我一直安慰自己扎瓶,他們只是感情好,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布泌枪。 她就那樣靜靜地躺著概荷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碌燕。 梳的紋絲不亂的頭發(fā)上误证,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音修壕,去河邊找鬼愈捅。 笑死,一個胖子當著我的面吹牛叠殷,可吹牛的內容都是我干的改鲫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼林束,長吁一口氣:“原來是場噩夢啊……” “哼像棘!你這毒婦竟也來了?” 一聲冷哼從身側響起壶冒,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤缕题,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后胖腾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烟零,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡瘪松,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锨阿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宵睦。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖墅诡,靈堂內的尸體忽然破棺而出壳嚎,到底是詐尸還是另有隱情,我是刑警寧澤末早,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布烟馅,位于F島的核電站,受9級特大地震影響然磷,放射性物質發(fā)生泄漏郑趁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一姿搜、第九天 我趴在偏房一處隱蔽的房頂上張望寡润。 院中可真熱鬧,春花似錦痪欲、人聲如沸悦穿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栗柒。三九已至,卻和暖如春知举,著一層夾襖步出監(jiān)牢的瞬間瞬沦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工雇锡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留逛钻,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓锰提,卻偏偏與公主長得像曙痘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子立肘,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容