版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.10.20 星期六 |
前言
SceneKit
使用高級(jí)場(chǎng)景描述創(chuàng)建3D游戲并將3D內(nèi)容添加到應(yīng)用程序。 輕松添加動(dòng)畫(huà),物理模擬,粒子效果和逼真的基于物理性的渲染。接下來(lái)這幾篇我們就詳細(xì)的解析一下這個(gè)框架。感興趣的看下面幾篇文章。
1. SceneKit框架詳細(xì)解析(一) —— 基本概覽(一)
2. SceneKit框架詳細(xì)解析(二) —— 基于SceneKit的簡(jiǎn)單游戲示例的實(shí)現(xiàn)(一)
3. SceneKit框架詳細(xì)解析(三) —— 基于SceneKit的簡(jiǎn)單游戲示例的實(shí)現(xiàn)(二)
4. SceneKit框架詳細(xì)解析(四) —— 基于SceneKit的簡(jiǎn)單游戲示例的實(shí)現(xiàn)(三)
5. SceneKit框架詳細(xì)解析(五) —— 基于SceneKit的簡(jiǎn)單游戲示例的實(shí)現(xiàn)(四)
開(kāi)始
在這部分中,您將為游戲添加一些很酷的粒子系統(tǒng)并將其包裝起來(lái)!
想象自己在電影院里手持爆米花;在屏幕上,一個(gè)來(lái)自“速度與激情”的壞人將他咆哮的高性能高速賽車(chē)撞到一輛高度不穩(wěn)定的油輪上,這輛油輪在一場(chǎng)巨大的死亡和大屠殺火球中爆炸。
現(xiàn)在,想想同樣的場(chǎng)景,但沒(méi)有大規(guī)模的火球爆炸。 你幾乎可以感受到世界各地觀眾的集體失望。
就像好萊塢大片一樣,你的游戲需要特效來(lái)提升興奮程度。 這些特殊效果以所謂的粒子系統(tǒng)(particle systems)
的形式出現(xiàn)。 您可以使用粒子系統(tǒng)來(lái)實(shí)現(xiàn)多種效果,從移動(dòng)星空,燃燒火箭助推器,到雨雪,到金屬火花 - 甚至是大型爆炸火球!
現(xiàn)在是時(shí)候看看如何將這些整潔的特效添加到Geometry Fighter
中。
Particle Systems - 粒子系統(tǒng)
在SceneKit
中,SCNParticleSystem
管理場(chǎng)景圖中粒子的創(chuàng)建,動(dòng)畫(huà)和移除。
粒子本質(zhì)上是一個(gè)小圖像精靈。粒子系統(tǒng)不會(huì)將單個(gè)粒子添加到場(chǎng)景圖本身中,因此您無(wú)法直接訪問(wèn)每個(gè)粒子;粒子系統(tǒng)管理粒子,包括它們的外觀,大小和位置。
但是,您可以通過(guò)修改粒子系統(tǒng)上的各種屬性來(lái)影響粒子系統(tǒng),例如:
- Appearance - 外觀:系統(tǒng)的每個(gè)粒子都可以渲染為單個(gè)圖像或動(dòng)畫(huà)圖像序列。您可以調(diào)整生成的粒子的大小,色調(diào)顏色,混合模式和其他渲染參數(shù)。
-
Life Span - 壽命:系統(tǒng)使用粒子發(fā)射器
(particle emitter)
,它產(chǎn)生每個(gè)單獨(dú)的粒子。粒子的壽命決定了它在場(chǎng)景中保持可見(jiàn)的時(shí)間。 - Emitter behavior - 發(fā)射器行為:您可以控制發(fā)射器的各種參數(shù),例如粒子生成的位置和生成率。
- Variation - 變化:在粒子系統(tǒng)中引入變體可以使其看起來(lái)更多或更少,隨機(jī)。
- Movement - 移動(dòng):您可以調(diào)整粒子在生成后的移動(dòng)方式。粒子使用簡(jiǎn)化的物理模擬來(lái)加速性能,但粒子仍然可以與物理引擎管理的對(duì)象進(jìn)行交互。
1. Creating a Trail Particle System - 創(chuàng)建跟蹤粒子系統(tǒng)
在將粒子系統(tǒng)添加到游戲世界之前,您需要一個(gè)組來(lái)容納此粒子系統(tǒng)以保持項(xiàng)目的有序性。 右鍵單擊GeometryFighter
組并選擇New Group
,如下所示:
將此新組命名為Particles
。 右鍵單擊該組,然后選擇New File
。 選擇iOS/Resource/SceneKit Particle System
,然后單擊Next
繼續(xù):
在下一個(gè)屏幕上,選擇Particle system template
的Fire
,然后單擊Next
。 將文件另存為Trail.scnp
,然后單擊Create
。 完成后,您應(yīng)該在場(chǎng)景中看到以下內(nèi)容:
以下是上面注釋的編輯器各個(gè)部分的快速概述:
- 1) Center stage - 中心面板:中心擁有您的粒子系統(tǒng)的直觀表示。您可以使用它來(lái)了解最終結(jié)果的樣子。
- 2) Gesture controls - 手勢(shì)控件:您可以使用手勢(shì)來(lái)操作相機(jī)視圖;它類(lèi)似于你在場(chǎng)景中移動(dòng)相機(jī)的方式。
- 3) Pause/Play button - 暫停/播放按鈕:您可以暫停粒子系統(tǒng)模擬并更詳細(xì)地檢查它。暫停時(shí),停按鈕變?yōu)椴シ虐粹o,您可以使用該按鈕恢復(fù)模擬。
- 4) Restart button - 重啟按鈕:這使您可以從頭開(kāi)始重新啟動(dòng)粒子模擬。
- 5) Camera reset button - 相機(jī)重置按鈕:使用此按鈕將相機(jī)視圖重置為默認(rèn)位置。
- 6) Color button - 顏色按鈕:這可讓您為編輯器設(shè)置合適的背景顏色;例如,在黑色背景下看雪花更容易。
- 7) Particle system properties - 粒子系統(tǒng)屬性:選擇
Attributes Inspector
會(huì)顯示一系列屬性,您將在下一節(jié)中了解這些屬性。
2. Configuring the Trail Particle System - 配置跟蹤粒子系統(tǒng)
在本節(jié)中,您將深入了解編輯器右側(cè)的粒子系統(tǒng)屬性。 在瀏覽每個(gè)部分時(shí),將屏幕截圖中每個(gè)設(shè)置的值復(fù)制到您自己的粒子系統(tǒng)中。
在更改每個(gè)屬性時(shí),請(qǐng)密切關(guān)注粒子系統(tǒng)編輯器;您將看到每個(gè)參數(shù)如何影響粒子系統(tǒng)的行為。 稍后,您將在游戲中使用此粒子效果來(lái)創(chuàng)建從生成的對(duì)象落下的粒子痕跡。
3. Emitter Attributes - 發(fā)射器屬性
粒子發(fā)射器是所有粒子產(chǎn)生的原點(diǎn)。 以下是發(fā)射器屬性:
- Birth rate - 出生率:控制粒子的排放率。將其設(shè)置為25,指示粒子引擎以每秒25個(gè)粒子的速率生成新粒子。
- Warmup duration - 預(yù)熱持續(xù)時(shí)間:模擬在渲染粒子之前運(yùn)行的秒數(shù)。這可以用于在開(kāi)始時(shí)顯示充滿(mǎn)粒子的屏幕,而不是等待粒子填滿(mǎn)屏幕。將其設(shè)置為0,以便可以從一開(kāi)始就查看模擬。
-
Location - 位置:相對(duì)于形狀的位置,發(fā)射器產(chǎn)生其粒子的位置。將其設(shè)置為
Vertex
,這意味著粒子將使用幾何頂點(diǎn)作為生成位置。 -
Emission space - 發(fā)射空間:發(fā)射粒子所在的空間。將其設(shè)置為
World Space
,以便將發(fā)射的粒子發(fā)射到世界空間,而不是對(duì)象節(jié)點(diǎn)本身的局部空間。 - Direction mode - 方向模式:控制衍生粒子的傳播方式;你可以將它們?nèi)恳苿?dòng)到一個(gè)恒定的方向,讓它們從形狀表面徑向向外移動(dòng),或者只是隨機(jī)移動(dòng)它們。將其設(shè)置為常量,使所有發(fā)射的粒子保持恒定方向。
-
Direction - 方向:指定方向模式恒定時(shí)使用的初始方向向量。將此向量設(shè)置為
(x:0,y:0,z:0)
,將方向設(shè)置為空。 - Spreading angle - 擴(kuò)散角度:隨機(jī)化產(chǎn)生的粒子的發(fā)射角度。將其設(shè)置為0°,從而精確地在先前設(shè)定的方向上發(fā)射粒子。
- Initial angle - 初始角度:發(fā)射粒子的初始角度。將其設(shè)置為0°,因?yàn)檫@與零方向矢量無(wú)關(guān)。
-
Shape - 形狀:發(fā)射粒子的形狀。將形狀設(shè)置為球體
(Sphere)
,因此使用球體形狀作為幾何體。 - Shape radius - 形狀半徑:此屬性的存在取決于您使用的形狀;對(duì)于球形發(fā)射器,這決定了球體的大小。將其設(shè)置為0.2,它定義了一個(gè)足夠大的球體,以滿(mǎn)足您的需要。
注意:請(qǐng)注意,某些屬性有兩個(gè)輸入?yún)^(qū)域,其中一個(gè)區(qū)域旁邊有一個(gè)
Δ=
符號(hào)(請(qǐng)參閱Birth Rate and Initial angle
)。第一個(gè)輸入?yún)^(qū)域包含基值,Δ=
輸入?yún)^(qū)域包含delta值。每次生成粒子時(shí),它都使用基值加上范圍內(nèi)的隨機(jī)值(-delta
值,+ delta值
)。這允許您為這些屬性獲得一些隨機(jī)方差。
4. Simulation Attributes - 模擬屬性
模擬屬性管理粒子在其生命周期內(nèi)的運(yùn)動(dòng)。 這使您無(wú)需使用物理引擎即可管理其移動(dòng):
- Life span - 壽命:以秒為單位指定粒子的壽命。將此值設(shè)置為1,以便單個(gè)粒子僅存在一秒鐘。
- Linear velocity - 線(xiàn)速度:指定發(fā)射粒子的線(xiàn)速度。將此值設(shè)置為0,這樣粒子就會(huì)產(chǎn)生沒(méi)有方向或速度的粒子。
- Angular velocity - 角速度:指定發(fā)射粒子的角速度。將其設(shè)置為0,這樣粒子就不會(huì)旋轉(zhuǎn)。
-
Acceleration - 加速度:指定應(yīng)用于發(fā)射粒子的力矢量。將其設(shè)置為
(x:0,y:-5,z:0)
- 這是向下矢量 - 一旦產(chǎn)生,以模擬粒子上的軟重力效應(yīng)。 - Speed factor - 速度系數(shù):設(shè)置粒子模擬速度的乘數(shù)。將其設(shè)置為1可以正常速度運(yùn)行模擬。
- Stretch factor - 拉伸因子:在運(yùn)動(dòng)方向上拉伸粒子的乘數(shù)。將其設(shè)置為0以不拉伸粒子圖像。
5. Image Attributes - 圖像屬性
圖像屬性控制粒子的視覺(jué)方面。它們還控制著這些粒子的外觀在其生命周期中如何變化:
-
Image - 圖像:指定將用于渲染每個(gè)粒子的圖像。選擇
CircleParticle.png
圖像,為粒子賦予其主要形狀。 - Color - 顏色:設(shè)置指定圖像的色調(diào)。將顏色設(shè)置為白色,為粒子系統(tǒng)提供白色的基色。
- Animate color - 動(dòng)畫(huà)顏色:使粒子在其生命周期內(nèi)改變顏色。取消選中此項(xiàng),因?yàn)榱W宇伾静粫?huì)改變。
-
Color variation - 顏色變化:為粒子顏色添加一點(diǎn)隨機(jī)性。您可以將其設(shè)置為
(h:0,s:0,b:0,a:0)
,因?yàn)榱W宇伾粫?huì)變化。 - Size - 大小:指定粒子的大小。將此值設(shè)置為0.1,以便發(fā)射的粒子尺寸較小。
6. Image Sequence Attributes - 圖像序列屬性
要為粒子創(chuàng)建動(dòng)畫(huà)圖像,可以將動(dòng)畫(huà)的每個(gè)幀排列到單個(gè)圖像上的網(wǎng)格中(如游戲中的精靈表)。然后,您只需將該網(wǎng)格圖像用作粒子發(fā)射器的圖像。使用圖像序列屬性可以控制粒子的基本動(dòng)畫(huà)屬性:
- Initial frame - 初始幀:設(shè)置動(dòng)畫(huà)序列的第一個(gè)從零開(kāi)始的幀。 第0幀對(duì)應(yīng)于網(wǎng)格中的左上圖像。 您正在使用單幀圖像,因此將其設(shè)置為0。
- Frame rate - 幀速率:以每秒幀數(shù)控制動(dòng)畫(huà)的速率。 將其設(shè)置為0,因?yàn)檫@僅適用于使用包含多個(gè)幀的圖像。
-
Animation - 動(dòng)畫(huà):指定動(dòng)畫(huà)序列的行為。 重復(fù)循環(huán)動(dòng)畫(huà),
Clamp
只播放一次,Auto Reverse
從開(kāi)始到結(jié)束播放,然后再播放。 你可以將它保留在Repeat
上,因?yàn)檫@在使用單幀圖像時(shí)無(wú)關(guān)緊要。 -
Dimensions - 尺寸:指定動(dòng)畫(huà)網(wǎng)格中的行數(shù)和列數(shù)。 將其設(shè)置為
(Rows: 1, Columns: 1)
,因?yàn)槟褂玫氖菃螏瑘D像。
7. Rendering Attributes - 渲染屬性
渲染屬性定義渲染階段如何處理粒子:
-
Blending - 混合:在將粒子繪制到場(chǎng)景中時(shí)指定渲染器的混合模式。 將其設(shè)置為
Alpha
,它將使用圖像Alpha通道信息進(jìn)行透明。 -
Orientation - 方向:控制粒子的旋轉(zhuǎn)。 將此設(shè)置為
Billboard screen-aligned
,這將使扁平粒子始終面向攝像機(jī)視圖,因此您不會(huì)注意到粒子確實(shí)是平面圖像。 -
Sorting - 排序:設(shè)置粒子的渲染順序。 此屬性與混合模式一起使用,并影響混合的應(yīng)用方式。 將其設(shè)置為
None
,以便粒子系統(tǒng)不會(huì)使用排序。 -
Lighting - 光照:控制
SceneKit
是否將光照應(yīng)用于粒子。 取消選中此選項(xiàng),粒子系統(tǒng)將忽略場(chǎng)景中的任何燈光。
8. Physics Attributes - 物理屬性
物理屬性允許您指定粒子在物理模擬中的行為方式:
- Affected by gravity - 受重力影響:使場(chǎng)景的重力影響粒子。 取消選中此項(xiàng),因?yàn)槟幌MW酉到y(tǒng)參與物理模擬。
- Affected by physics fields - 受物理場(chǎng)影響:導(dǎo)致場(chǎng)景中的物理場(chǎng)影響粒子。 取消選中此項(xiàng),因?yàn)槟幌M锢韴?chǎng)對(duì)粒子產(chǎn)生影響。
- Die on Collision - 死于碰撞:讓場(chǎng)景中的物理體碰撞并破壞粒子。 取消選中此項(xiàng),因?yàn)槟幌M谂c場(chǎng)景中的節(jié)點(diǎn)對(duì)象發(fā)生碰撞時(shí)刪除粒子。
- Physics Properties - 物理屬性:在物理模擬過(guò)程中控制粒子物理行為的基本物理屬性。 您可以將所有這些保留為默認(rèn)值,因?yàn)榱W酉到y(tǒng)不會(huì)使用它。
9. Life Cycle Attributes - 生命周期屬性
生命周期屬性可讓您控制粒子系統(tǒng)的整個(gè)生命周期:
- Emission duration - 發(fā)射持續(xù)時(shí)間:控制發(fā)射器發(fā)射新粒子的時(shí)間長(zhǎng)度。 將其設(shè)置為1,這將激活粒子發(fā)射器,總長(zhǎng)度為1秒。
- Idle duration - 空閑持續(xù)時(shí)間:循環(huán)粒子系統(tǒng)在指定的發(fā)射持續(xù)時(shí)間內(nèi)發(fā)射粒子,然后在指定的空閑持續(xù)時(shí)間內(nèi)空閑,之后循環(huán)重復(fù)。 將其設(shè)置為0,這樣粒子系統(tǒng)將只發(fā)射一次。
-
Looping - 循環(huán):指定粒子系統(tǒng)是否發(fā)射一次粒子,如爆炸,或連續(xù)發(fā)射,如火山。 將其設(shè)置為
Loops continuously
,以便發(fā)射器在再次從場(chǎng)景中移除之前盡可能長(zhǎng)時(shí)間地發(fā)射。
對(duì)于單個(gè)粒子系統(tǒng),需要考慮很多屬性,但這可以讓您獲得很多控制以獲得您正在尋找的特別的特效。
如果您努力將屏幕截圖中的值復(fù)制到粒子系統(tǒng),您將擁有一個(gè)代表以下效果的系統(tǒng):
如果您的不是這樣,請(qǐng)嘗試旋轉(zhuǎn)相機(jī)。 它也可能有助于將背景顏色更改為深藍(lán)色,就像您在此處看到的那樣,可以更容易地看到粒子系統(tǒng)。
現(xiàn)在終于可以為游戲添加炫酷粒子效果了。 將以下內(nèi)容添加到GameViewController.swift
類(lèi):
// 1
func createTrail(color: UIColor, geometry: SCNGeometry) ->
SCNParticleSystem {
// 2
let trail = SCNParticleSystem(named: "Trail.scnp", inDirectory: nil)!
// 3
trail.particleColor = color
// 4
trail.emitterShape = geometry
// 5
return trail
}
以下是上面發(fā)生的事情:
- 1) 這定義了
createTrail(_:geometry :)
,它接受color
和geometry
參數(shù)來(lái)設(shè)置粒子系統(tǒng)。 - 2) 這將從您之前創(chuàng)建的文件加載粒子系統(tǒng)。
- 3) 在這里,您可以根據(jù)傳入的參數(shù)修改粒子的色調(diào)顏色。
- 4) 這使用
geometry
參數(shù)指定發(fā)射器的形狀。 - 5) 最后,這將返回新創(chuàng)建的粒子系統(tǒng)。
此方法可幫助您創(chuàng)建SCNParticleSystem
的實(shí)例,但仍需要將粒子系統(tǒng)添加到生成的形狀對(duì)象。
請(qǐng)注意,createTrail(_:geometry :)
接受一個(gè)顏色參數(shù)并使用它來(lái)為粒子著色。 您將粒子系統(tǒng)的顏色設(shè)置為與形狀的顏色相同。
在spawnShape()
中找到在其中設(shè)置形狀的材質(zhì)漫反射內(nèi)容的那一行,然后將其拆分,使隨機(jī)顏色存儲(chǔ)在常量中,如下所示:
let color = UIColor.random()
geometry.materials.first?.diffuse.contents = color
接下來(lái),在將力強(qiáng)加到geometryNode
的物理體之后,在spawnShape()
中進(jìn)一步向下添加以下行:
let trailEmitter = createTrail(color: color, geometry: geometry)
geometryNode.addParticleSystem(trailEmitter)
這使用createTrail(_:geometry :)
創(chuàng)建粒子系統(tǒng)并將其附加到geometryNode
。
構(gòu)建并運(yùn)行,看看你的辛勤工作!
它看起來(lái)很棒 !
Heads-up Displays
在這個(gè)簡(jiǎn)短的部分中,您將使用Game Utils
快速添加一個(gè)小小的抬頭顯示器來(lái)顯示您的玩家的剩余生命,最佳分?jǐn)?shù)和當(dāng)前分?jǐn)?shù)。 幕后代碼使用SpriteKit
標(biāo)簽,并使用標(biāo)簽的輸出作為平面的紋理。 這是一種強(qiáng)大的技術(shù)!
將以下新屬性添加到gamewnController.swift
,就在spawnTime
下面:
var game = GameHelper.sharedInstance
這使您可以快速訪問(wèn)GameHelper
共享實(shí)例,該實(shí)例包含一組方法來(lái)為您完成繁重的工作。
將以下方法添加到GameViewController
的底部,在createTrail()
下面:
func setupHUD() {
game.hudNode.position = SCNVector3(x: 0.0, y: 10.0, z: 0.0)
scnScene.rootNode.addChildNode(game.hudNode)
}
在這里,您可以使用幫助程序庫(kù)中的game.hudNode
。 您設(shè)置HUD節(jié)點(diǎn)的位置并將其添加到場(chǎng)景中。
接下來(lái),您需要從某個(gè)地方調(diào)用setupHUD()
。 將以下行添加到viewDidLoad()
的底部:
setupHUD()
現(xiàn)在你有一個(gè)抬頭顯示器,你需要保持它是最新的。 將以下調(diào)用game.updateHUD()
添加到到renderer(_: updateAtTime:)
的底部。
game.updateHUD()
構(gòu)建并運(yùn)行,您將在屏幕頂部看到您的顯示,如下所示:
你的游戲現(xiàn)在有一個(gè)漂亮的小HUD,有生命計(jì)數(shù)器,高分和當(dāng)前分?jǐn)?shù)。
好的,抬頭顯示很好,但現(xiàn)在是時(shí)候?yàn)槟愕挠螒蛱砑右恍┗?dòng)了。
Touch Handling - 觸摸處理
通常情況下,在您的應(yīng)用中啟用觸摸并不像人們希望的那樣簡(jiǎn)單。
第一步是了解觸摸處理在3D中的工作原理。 下圖顯示了場(chǎng)景側(cè)視圖中的觸摸點(diǎn)以及SceneKit
如何將該觸摸點(diǎn)轉(zhuǎn)換為3D場(chǎng)景以確定您正在觸摸的對(duì)象:
那么您采取了哪些步驟來(lái)處理用戶(hù)的觸摸事件?
- Get touch location - 獲取觸摸位置:首先,您需要在屏幕上獲取用戶(hù)觸摸的位置。
-
Convert to view coordinates - 轉(zhuǎn)換為視圖坐標(biāo):之后,您需要將該觸摸位置轉(zhuǎn)換為相對(duì)于呈現(xiàn)場(chǎng)景的
SCNView
實(shí)例的位置。 - Fire a ray for a hit test - 為命中測(cè)試射出一條光線(xiàn):一旦你建立了一個(gè)相對(duì)于視圖的觸摸位置,SceneKit就可以通過(guò)向你的場(chǎng)景發(fā)射一條光線(xiàn)(不是,不是那個(gè)Ray!)來(lái)為你執(zhí)行命中測(cè)試并返回一個(gè) 與光線(xiàn)相交的對(duì)象列表。
1. Naming Nodes - 命名節(jié)點(diǎn)
在激活觸摸死亡之前,您需要一種方法來(lái)識(shí)別每個(gè)衍生對(duì)象。 最簡(jiǎn)單的方法是給他們起名字。
將粒子系統(tǒng)添加到geometryNode
后立即將以下內(nèi)容添加到spawnShape()
:
if color == UIColor.black {
geometryNode.name = "BAD"
} else {
geometryNode.name = "GOOD"
}
秉承古老西方電影黑帽惡魔的精神,你將綽號(hào)BAD
分配給黑色物體,并將GOOD
分配給所有其他物體。
2. Adding Touch Handling - 添加觸摸處理
接下來(lái),您需要編寫(xiě)一個(gè)方法,以便在檢測(cè)到用戶(hù)已觸發(fā)特定節(jié)點(diǎn)時(shí)稍后調(diào)用該方法。
將以下方法添加到GameViewController
的底部,在setupHUD()
下面:
func handleTouchFor(node: SCNNode) {
if node.name == "GOOD" {
game.score += 1
node.removeFromParentNode()
} else if node.name == "BAD" {
game.lives -= 1
node.removeFromParentNode()
}
}
該方法檢查被觸摸節(jié)點(diǎn)的名字;良好的節(jié)點(diǎn)會(huì)增加分?jǐn)?shù),而糟糕的(黑色)節(jié)點(diǎn)會(huì)將生命數(shù)量減少一個(gè)。 在任何一種情況下,您都會(huì)從屏幕中刪除節(jié)點(diǎn),因?yàn)樗驯讳N(xiāo)毀。
3. Using the Touch Handler - 使用觸控處理程序
要捕獲用戶(hù)的觸摸,您將使用touchesBegan(_:withEvent :)
,每次玩家觸摸屏幕時(shí)都會(huì)調(diào)用它。
要實(shí)現(xiàn)您自己的版本,請(qǐng)?jiān)?code>GameViewController中handleTouchFor(_ :)
下面添加以下內(nèi)容:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 1
let touch = touches.first!
// 2
let location = touch.location(in: scnView)
// 3
let hitResults = scnView.hitTest(location, options: nil)
// 4
if let result = hitResults.first {
// 5
handleTouchFor(node: result.node)
}
}
下面進(jìn)行細(xì)分:
- 1) 抓住第一個(gè)可用的
touch
。 如果玩家使用多個(gè)手指,則可以有多個(gè)。 - 2) 將觸摸位置轉(zhuǎn)換為相對(duì)于
scnView
坐標(biāo)的位置。 - 3)
hitTest(_:options :)
為您提供了一個(gè)SCNHitTestResult
對(duì)象數(shù)組,這些對(duì)象表示從用戶(hù)觸摸的視圖內(nèi)的點(diǎn)開(kāi)始并遠(yuǎn)離相機(jī)的光線(xiàn)的任何交叉點(diǎn)。 - 4) 檢查命中測(cè)試的第一個(gè)結(jié)果。
- 5) 最后,您將第一個(gè)結(jié)果節(jié)點(diǎn)傳遞給您的觸摸處理程序,這將增加您的分?jǐn)?shù) - 或者讓您失去生命!
最后一步。 您不再需要攝像頭控制,因此請(qǐng)更改setupView()
中的行,如下所示:
scnView.allowsCameraControl = false
構(gòu)建并運(yùn)行,準(zhǔn)備好釋放你的手指!
點(diǎn)擊產(chǎn)生的物體,使它們分解在稀薄的空氣中。
Challenge - 挑戰(zhàn)
是時(shí)間到很酷的因素 - 什么比爆炸更酷? 絕對(duì)沒(méi)有,對(duì)吧?
這將帶您接受本教程的挑戰(zhàn),即創(chuàng)建另一個(gè)粒子系統(tǒng)并將其命名為Explode.scnp
。 看看你是否可以找出要修改的屬性以使這些粒子爆炸。
效果看起來(lái)應(yīng)該與此類(lèi)似:
您可以使用以下圖像作為粒子系統(tǒng)的起點(diǎn):
Shaping Particle Explosions - 塑造粒子爆炸
現(xiàn)在您已經(jīng)創(chuàng)建了爆炸粒子系統(tǒng),您需要添加一些代碼來(lái)使這些節(jié)點(diǎn)爆炸。 您將使用一些特殊屬性來(lái)使爆炸與您觸摸的任何節(jié)點(diǎn)具有相同的形狀。
將以下內(nèi)容添加到GameViewController
的底部,在touchesBegan(_:withEvent)
下面:
// 1
func createExplosion(geometry: SCNGeometry, position: SCNVector3,
rotation: SCNVector4) {
// 2
let explosion =
SCNParticleSystem(named: "Explode.scnp", inDirectory:
nil)!
explosion.emitterShape = geometry
explosion.birthLocation = .surface
// 3
let rotationMatrix =
SCNMatrix4MakeRotation(rotation.w, rotation.x,
rotation.y, rotation.z)
let translationMatrix =
SCNMatrix4MakeTranslation(position.x, position.y,
position.z)
let transformMatrix =
SCNMatrix4Mult(rotationMatrix, translationMatrix)
// 4
scnScene.addParticleSystem(explosion, transform: transformMatrix)
}
以下是上述代碼的細(xì)分:
- 1)
createExplosion(_:position:rotation :)
有三個(gè)參數(shù):geometry
定義粒子效果的形狀,而position
和rotation
幫助將爆炸放入場(chǎng)景中。 - 2) 這會(huì)加載
Explode.scnp
并使用它來(lái)創(chuàng)建一個(gè)發(fā)射器。 發(fā)射器使用geometry
作為emitterShape
,因此粒子將從形狀的表面發(fā)射。 - 3) 輸入矩陣!不要被這三條線(xiàn)嚇到;它們只是為
addParticleSystem(_:withTransform :)
提供了一個(gè)組合的旋轉(zhuǎn)和位置(或轉(zhuǎn)換)轉(zhuǎn)換矩陣。 - 4) 最后,在
scnScene
上調(diào)用addParticleSystem(_:wtihTransform)
將爆炸添加到場(chǎng)景中。
你是如此接近復(fù)制那些偉大的好萊塢爆炸! 在handleTouchFor(_ :)
中兩次添加以下行 - 一次到“good”if
塊,一次到“bad”else
塊,就在從父節(jié)點(diǎn)移除節(jié)點(diǎn)之前:
createExplosion(geometry: node.geometry!,
position: node.presentation.position,
rotation: node.presentation.rotation)
這使用presentation
屬性來(lái)檢索節(jié)點(diǎn)的position
和rotation
參數(shù)。 然后使用這些參數(shù)調(diào)用createExplosion(_:position:rotation :)
。
注意:您正在使用
presentation
,因?yàn)槲锢砟M當(dāng)前正在移動(dòng)節(jié)點(diǎn)。
構(gòu)建并運(yùn)行,點(diǎn)擊,讓這些節(jié)點(diǎn)爆炸!
注意:您可以在
projects / challenge / GeometryFighter
文件夾下找到此挑戰(zhàn)的項(xiàng)目。
Adding Juice
你的游戲尚未完成;還有很大的改進(jìn)空間,對(duì)吧?要將游戲推向更高級(jí)別,您必須添加一些稱(chēng)為juice
的東西。juice
會(huì)給你的游戲帶來(lái)一些特別的東西,只是為了讓它在其余部分中脫穎而出。
這里有一些想法肯定會(huì)讓事情變得更好:
-
Game state management - 游戲狀態(tài)管理:通過(guò)基本的游戲狀態(tài)管理,您將能夠根據(jù)
TapToPlay
,Playing
或GameOver
等游戲狀態(tài)控制某些游戲機(jī)制。 - Splash screens - 啟動(dòng)畫(huà)面:使用漂亮的濺射屏幕。它們?yōu)橥婕姨峁┊?dāng)前游戲狀態(tài)的視覺(jué)線(xiàn)索。
- Sound effects - 聲音效果:添加炫酷的聲音效果,為玩家提供與游戲元素良好互動(dòng)的重要音頻反饋。
- Camera shakes - 相機(jī)震動(dòng):真正的大爆炸產(chǎn)生了非常大的沖擊波。添加搖動(dòng)相機(jī)效果,為您的游戲增添一些額外的東西。
后記
本篇主要講述了基于SceneKit的簡(jiǎn)單游戲示例的實(shí)現(xiàn),感興趣的給個(gè)贊或者關(guān)注~~~