SceneKit 使用的是 SpriteKit的轉(zhuǎn)場(chǎng)動(dòng)畫, 這就是為什么上一章我們導(dǎo)入了SpriteKit.
SKTransition 可以讓你從一個(gè)scene動(dòng)畫到下一個(gè)scene, 有下面很多種效果可供選擇:
- crossFade(withDuration:): 淡入淡出
- doorsCloseHorizontal(withDuration:): 就像水平方向關(guān)閉兩扇門
- doorsCloseVertical(withDuration:): 就像垂直方向關(guān)閉兩扇門
- doorsOpenHorizontal(withDuration:): 就像水平方向打開兩扇門
- doorsOpenVertical(withDuration:): 像水垂直方向打開兩扇門
- doorway(withDuration:): 開門的同時(shí)要展示的scene縮放
- fade(withColor:): 當(dāng)前scene先漸變?yōu)橐粋€(gè)顏色然后新scene漸變展示
- fade(withDuration:): 當(dāng)前scene先漸變?yōu)楹谏缓笮聅cene漸變展示
- flipHorizontal(withDuration:): 水平翻轉(zhuǎn)180°
- flipVertical(withDuration:): 垂直翻轉(zhuǎn)180°
- moveIn(withDirection:): 在當(dāng)前scene上層蓋上新scene
- push(withDirection:): 當(dāng)前scene被新scene推出
- reveal(withDirection:): 當(dāng)前scene向一個(gè)方向滑出
- transition(withCIFilter:): 用Core Image Filters作為轉(zhuǎn)場(chǎng)效果
添加轉(zhuǎn)場(chǎng)特效
你要添加方法來控制游戲的三個(gè)狀態(tài):playing, tapToPlay, gameOver. 這樣在切換游戲狀態(tài)時(shí), 添加不同的轉(zhuǎn)場(chǎng)動(dòng)畫.
首先來添加第一個(gè)方法, 讓你的游戲切換的playing狀態(tài), 并將splash scene轉(zhuǎn)場(chǎng)到game scene, 添加下面方法到ViewController:
func startGame() {
//現(xiàn)在假設(shè)你的游戲都從splash scene開始, 所以你要做的第一件事是手動(dòng)暫停splash scene, 這樣會(huì)停止splash scene上所有的action跟物理效果
splashScene.isPaused = true
//這是你如何來創(chuàng)建一個(gè)轉(zhuǎn)場(chǎng)
let transition = SKTransition.doorsOpenVertical(withDuration: 1)
//這里你通過調(diào)用SCNView的present方法并傳入你剛創(chuàng)建的轉(zhuǎn)場(chǎng), 你可以指定轉(zhuǎn)場(chǎng)的觀點(diǎn)(point of view), 但由于目前只有一個(gè)camera所以將此處置為nil.
scnView.present(gameScene, with: transition, incomingPointOfView: nil) {
//這里的代碼在轉(zhuǎn)場(chǎng)動(dòng)畫完成時(shí)執(zhí)行, 此時(shí)我們將游戲狀態(tài)設(shè)置為playing, 并調(diào)用設(shè)置聲效的方法
self.game.state = .playing
self.setupSounds()
self.gameScene.isPaused = false
}
}
當(dāng)豬大哥被車裝時(shí), 我們下面的方法將游戲狀態(tài)設(shè)置為gameOver,
添加下面方法到ViewController:
func stopGame() {
game.state = .gameOver
game.reset()
}
這段代碼首先將狀態(tài)設(shè)置為gameOver, 然后重置游戲來準(zhǔn)備重新開始游戲.
最后這個(gè)方法將游戲狀態(tài)改為tapToPlay, 即splash scene呈現(xiàn)給玩家時(shí)的狀態(tài),
添加下面方法到ViewController:
func startSplash() {
gameScene.isPaused = true
let transition = SKTransition.doorway(withDuration: 1)
scnView.present(splashScene, with: transition, incomingPointOfView: nil) {
self.game.state = .tapToPlay
self.setupSounds()
self.splashScene.isPaused = false
}
}
這個(gè)方法跟前面startGame()十分像我就不寫注釋了, 現(xiàn)在你有了控制游戲狀態(tài)的所有基本方法.
還需要下面這個(gè)小方法來監(jiān)聽用戶的點(diǎn)擊手勢(shì),
添加下面方法到ViewController:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
if game.state == .tapToPlay {
startGame()
}
}
每當(dāng)玩家手指觸摸到屏幕時(shí), touchesBegan(_:event:)就會(huì)觸發(fā), 此時(shí)判斷如果正處于TapToPlay狀態(tài), 就是玩家想開始游戲, 所以你調(diào)用startGame()方法.
command + R來測(cè)試你的轉(zhuǎn)場(chǎng)效果.
(由于模擬器的性能較低, 很可能會(huì)完全看不到動(dòng)畫, 所以這里建議用真機(jī)運(yùn)行. 在我寫這篇文章的時(shí)候有兩個(gè)很惱人的問題困擾我了很長(zhǎng)時(shí)間, 不過好像都是跟iPhone X有關(guān). 首先是有可能閃退, 在我完全沒有更改我代碼的情況下, 第一天運(yùn)行ok第二天閃退了, "does not match the framebuffer's pixelFormat "之類的, 查了一下好像不是我一個(gè)人的問題, 閃退可以通過Edit Scheme -> Options -> Metal API Validation : Disabled 來解決; 然后就是第二個(gè)問題, 動(dòng)畫時(shí)整個(gè)view的顏色會(huì)變成奇怪的藍(lán)色. 這個(gè)問題還沒找到原因與解決方法. 有知道的大佬求指點(diǎn). Pixel Format Error with SceneKit + SpriteKit Overlay on iPhone X.
)
目錄 (不定期更新中 :] )
1 準(zhǔn)備工作、創(chuàng)建項(xiàng)目、Splash Scene
2 過場(chǎng)動(dòng)畫 Transition
3 搭建游戲場(chǎng)景 Game Scene
4 用場(chǎng)景編輯器添加動(dòng)作
5 用代碼添加動(dòng)作