說明
本系列文章是對<3D Apple Games by Tutorials>一書的學習記錄和體會
更多iOS相關知識檢視github上WeekWeekUpProject
以前面的遊戲為例,將其改為跨平臺版本:
- macOS遊戲Geometry Fighter
- tvOS遊戲Breaker
- watchOS遊戲Geometry Fighter
16-macOS遊戲Geometry Fighter
建立專案
開啟Xcode建立新專案,選擇macOS平臺,選擇Game型別,點選Next繼續.
輸入遊戲名SceneKitGame,選擇Swift語言,SceneKit遊戲技術,取消Unit和UI Tests,點選Finish.
生成的專案類似於iOS專案,但不完全相同:
- GameView.swift:繼承於SCNView,可以響應滑鼠鍵盤事件但不能觸控.
- GameViewController.swift:繼承於NSViewController.
- MainMenu.xib:控制器的xib.
選擇My Mac,執行一下游戲:
轉換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內容共享
可以在iOS和macOS之間共享原來的程式碼和資源.建立一個Shared分組
將下列檔案和資料夾移動到Shared下面:
按住Shift鍵,選中GeometryFighter/ Shared/Particles下面的全部檔案,開啟右側的屬性檢查器,勾選Target Membership下面的GeometryFighterMac;這樣就能在iOS target和macOS target之間共享了.
Shared下面的其他幾個也是類似操作.
為了解決跨平臺帶來的問題,還需要新增下列程式碼:
#if os(iOS)
import UIKit
#endif
#if os(macOS)
import Cocoa
#endif
複製程式碼
當然了,我們不需要每個檔案都去新增,只需要將已建立好的resources/ GameUtils/ 檔案匯入進來就可以了.首先,刪除一些舊檔案,選中GameHelper.swift和UIColor+Extensions.swift. 右鍵--刪除--Move to Trash. 將resources/ GameUtils/ 下面的所有檔案拖放到Shared/ GameUtils/ 資料夾下
清理
還需要清理一下專案.選中GameView.swift, GameViewController.swift和art.scnassets.右鍵刪除--Move to Trash.
然後從示例程式碼中本章節的resources/GameViewController資料夾下拖放GameView.swift和GameViewController.swift到專案中,選中Copy items if needed和GeometryFighterMac,點選Finish完成.
還要做的是恢復新的GameViewController與MainMenu.xib之間的聯絡.
滑鼠輸入
選中MainMenu.xib,從右側物件庫中拖放一個Click Gesture Recognizer到Game View中.
新增連線函式:
現在還差最後一步,新增AppIcon,你可以從本章節的resources/AppIcon/資料夾中找到,拖放到Assets.xcassets中的AppIcon下:
執行一下程式:
本專案的最終完成版程式碼可以在對應章節的projects/ final/GeometryFighter/ 下找到.
17-tvOS遊戲Breaker
建立專案
建立專案
在Active Scheme中選擇SceneKitGame > tvOS Simulator > Apple TV 1080p:
執行一下,可以看到預設的飛機模型.但是真實的Apple TV是要用遙控器操作的,怎麼用呢?在模擬器的Hardware > Show Apple TV Remote中,就可以調出遙控器了:
移植到tvOS
在程式碼中找到本章節的projects/ starter/Breaker/ 資料夾接著處理.
和前面類似,選中Breaker,新增新的target,在彈出窗中選擇tvOS和Game.
targets間內容共享
新增一個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
複製程式碼
圖示
圖示資源在本章節對應的resources資料夾下.
開啟BreakerTV/Assets.xcassets,選中App Icon & Top Shelf Image,將圖片拖放進去:
執行一下,看到圖示出現在Apple TV首頁上了:
點選進入遊戲,開始玩吧:
18-watchOS遊戲Geometry Fighter
在Xcode中,並沒有專門的watchOS版遊戲的模板,我們需要做的是建立一個iOS的遊戲,再給它新增watchOS的支援.
新增watchOS支援
我們直接在原iOS專案基礎上新增watchOS的target:
在Active Scheme中選擇GeometryFighterWatch > iPhone 6s Plus + Apple Watch - 42mm
執行一下,看看效果:
targets間內容共享
建立Shared資料夾,移動需要的檔案
然後依次選中各個資料夾下面的所有檔案,新增Target Membership:
新增介面控制器
首先清理專案,選中InterfaceController.swift和art.scnassets.右鍵--刪除--Move to Trash.
現在需要新增新的InterfaceController.swift.在本章節對應程式碼的resources/source資料夾下,拖放到Xcode中.
然後建立連線:
新增觸控輸入
選中Interface.storyboard,拖放一個Tap Gesture Recognizer過來.
建立手勢的連線:
現在已經基本完成了.
圖示
所需圖片資源在本章節對應的resource/AppIcon資料夾下.
選中Assets.xcassets下面的AppIcon,將圖片拖放到其中:
執行一下,可以愉快地玩耍了!
專案的最終完成版本章節對應的projects/ final/GeometryFighter/ 資料夾下.