說明
本系列文章是對<3D Apple Games by Tutorials>一書的學習記錄和體會此書對應的代碼地址
更多iOS相關(guān)知識查看github上WeekWeekUpProject
以前面的游戲為例,將其改為跨平臺版本:
-
macOS游戲Geometry Fighter
WX20171202-194556@2x.png -
tvOS游戲Breaker
WX20171202-194627@2x.png -
watchOS游戲Geometry Fighter
WX20171202-194641@2x.png
16-macOS游戲Geometry Fighter
創(chuàng)建項目
打開Xcode創(chuàng)建新項目,選擇macOS平臺,選擇Game類型,點擊Next繼續(xù).
輸入游戲名SceneKitGame,選擇Swift語言,SceneKit游戲技術(shù),取消Unit和UI Tests,點擊Finish.
生成的項目類似于iOS項目,但不完全相同:
- GameView.swift:繼承于SCNView,可以響應鼠標鍵盤事件但不能觸摸.
- GameViewController.swift:繼承于NSViewController.
- MainMenu.xib:控制器的xib.
選擇My Mac,運行一下游戲:
轉(zhuǎn)換SceneKit游戲
可以在projects/ starter/GeometryFighter/中打到原iOS版的項目.
打開iOS版項目,點擊GeometryFighter,添加新的target:
選擇Add Target...
選擇macOS平臺,然后選擇Game
輸入項目名GeometryFighterMac,選擇SceneKit,取消Unit Tests和UI Tests,點擊Finish:
選擇GeometryFighterMac > My Mac作為Active Scheme.
運行后,看到的還是默認的飛機場景,那是因為還需要其他步驟.
多個target內(nèi)容共享
可以在iOS和macOS之間共享原來的代碼和資源.創(chuàng)建一個Shared分組
將下列文件和文件夾移動到Shared下面:
按住Shift鍵,選中GeometryFighter/ Shared/Particles下面的全部文件,打開右側(cè)的屬性檢查器,勾選Target Membership下面的GeometryFighterMac;這樣就能在iOS target和macOS target之間共享了.
Shared下面的其他幾個也是類似操作.
為了解決跨平臺帶來的問題,還需要添加下列代碼:
#if os(iOS)
import UIKit
#endif
#if os(macOS)
import Cocoa
#endif
當然了,我們不需要每個文件都去添加,只需要將已創(chuàng)建好的resources/ GameUtils/文件導入進來就可以了.首先,刪除一些舊文件,選中GameHelper.swift和UIColor+Extensions.swift.
右鍵--刪除--Move to Trash.
將resources/ GameUtils/下面的所有文件拖放到Shared/ GameUtils/文件夾下
清理
還需要清理一下項目.選中GameView.swift, GameViewController.swift和art.scnassets.右鍵刪除--Move to Trash.
然后從示例代碼中本章節(jié)的resources/GameViewController文件夾下拖放GameView.swift和GameViewController.swift到項目中,選中Copy items if needed和GeometryFighterMac,點擊Finish完成.
還要做的是恢復新的GameViewController與MainMenu.xib之間的聯(lián)系.
鼠標輸入
選中MainMenu.xib,從右側(cè)對象庫中拖放一個Click Gesture Recognizer到Game View中.
添加連接函數(shù):
現(xiàn)在還差最后一步,添加AppIcon,你可以從本章節(jié)的resources/AppIcon/文件夾中找到,拖放到Assets.xcassets中的AppIcon下:
運行一下程序:
本項目的最終完成版代碼可以在對應章節(jié)的projects/ final/GeometryFighter/下找到.
17-tvOS游戲Breaker
創(chuàng)建項目
創(chuàng)建項目
在Active Scheme中選擇SceneKitGame > tvOS Simulator > Apple TV 1080p:
運行一下,可以看到默認的飛機模型.但是真實的Apple TV是要用遙控器操作的,怎么用呢?在模擬器的Hardware > Show Apple TV Remote中,就可以調(diào)出遙控器了:
移植到tvOS
在代碼中找到本章節(jié)的projects/ starter/Breaker/文件夾接著處理.
和前面類似,選中Breaker,添加新的target,在彈出窗中選擇tvOS和Game.
targets間內(nèi)容共享
添加一個Shared分組,并將原來的文件拖放進來:
逐一選中文件夾下的所有文件,添加Target Membership:
還需要清理一下代碼.
選中BreakerTV/art.scnassets和BreakerTV/GameViewController.swift,刪除--Move To Trash:
添加專用代碼
打開GameViewController.swift,在setupNodes()
末尾添加代碼:
#if os(tvOS)
scnView.pointOfView = horizontalCameraNode
#endif
還有shouldAutorotate
, prefersStatusBarHidden
和viewWillTransition()
也不需要了:
#if os(iOS)
override var shouldAutorotate: Bool {
... }
override var prefersStatusBarHidden: Bool {
... }
override func viewWillTransition(to size: CGSize, with coordinator:
UIViewControllerTransitionCoordinator) {
... }
#endif
遙控觸摸事件
和iOS的觸摸事件不同,遙控上更接近MacBook的觸摸板的邏輯,touchesBegin()
的初始位置總是(x:960, y: 540)
,即1080p顯示器的中心,touchesMoved()
時的位置則是相對于初始點的位置.
另外還有一個問題:tvOS遙控器的觸摸板太靈敏了,輕微移動就是很長距離.我們需要在GameViewController
中找到下面的代碼:
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.1)
將其更改為:
#if os(iOS)
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.1)
#elseif os(tvOS)
paddleNode.position.x = paddleX +
(Float(location.x - touchX) * 0.01)
#endif
圖標
圖標資源在本章節(jié)對應的resources文件夾下.
打開BreakerTV/Assets.xcassets,選中App Icon & Top Shelf Image,將圖片拖放進去:
運行一下,看到圖標出現(xiàn)在Apple TV首頁上了:
點擊進入游戲,開始玩吧:
18-watchOS游戲Geometry Fighter
在Xcode中,并沒有專門的watchOS版游戲的模板,我們需要做的是創(chuàng)建一個iOS的游戲,再給它添加watchOS的支持.
添加watchOS支持
我們直接在原iOS項目基礎(chǔ)上添加watchOS的target:
在Active Scheme中選擇GeometryFighterWatch > iPhone 6s Plus + Apple Watch - 42mm
運行一下,看看效果:
targets間內(nèi)容共享
創(chuàng)建Shared文件夾,移動需要的文件
然后依次選中各個文件夾下面的所有文件,添加Target Membership:
添加界面控制器
首先清理項目,選中InterfaceController.swift和art.scnassets.右鍵--刪除--Move to Trash.
現(xiàn)在需要添加新的InterfaceController.swift.在本章節(jié)對應代碼的resources/source文件夾下,拖放到Xcode中.
然后建立連接:
添加觸摸輸入
選中Interface.storyboard,拖放一個Tap Gesture Recognizer過來.
建立手勢的連接:
現(xiàn)在已經(jīng)基本完成了.
圖標
所需圖片資源在本章節(jié)對應的resource/AppIcon文件夾下.
選中Assets.xcassets下面的AppIcon,將圖片拖放到其中:
運行一下,可以愉快地玩耍了!
項目的最終完成版本章節(jié)對應的projects/ final/GeometryFighter/文件夾下.