建置應用程序很不簡單,但是做遊戲其實更難,特別是開發者本身不是一個玩家,雖然每當我開始學習遊戲編程時,都會這樣對自己說,最終卻都退卻了。今年,我終於意識到我做錯了:過去太專注在建立一個大的東西,因此從一開始就害怕眼前的巨大任務,但應該是從小的部分開始,保持愉快的開發步調。我們想製作有趣的遊戲,所以如果沒有享受創造它們的樂趣,那如何抓得到重點呢?因此,我得到了啟發:你不必從頭開始創建一個完整的遊戲,你只需要想到一些簡易的任務來起頭,其餘的就會自然發展下去。
在這個系列教程中,你會面對一個簡單的挑戰:藉由SpriteKit與Apple的2D遊戲框架,當你點擊屏幕時,將會同時讓標籤移動,縮放和旋轉,以下為本文讀者需要了解的概念:
Scenes
Nodes
Labels
Points
Gesture recognisers
Actions
這些概念實際上是相當豐富的,所以讓我們開始吧!
本系列教程介紹
在本系列的第一個部分中,透過將標籤(labels)置中在屏幕畫面的動作,來了解關於場景(scenes)、節點(nodes)、標籤(labels)和座標點(points)的所有知識。第二部分藉由移動,縮放和旋轉標籤,來教你關於手勢識別和動作的全部用法。
你可能會想,為什麼我會在系列教程的第一部分,教你如何將標籤置中。這不是很容易嗎?
學習顯示並置中卷標的動作,是剛開始學習場景和節點並且將它們融會貫通最簡單的方法。在學習進階內容(如手勢識別和動作)之前,先了解如何定位標籤,以及操作節點和場景是非常重要的。
如果你沒有理解和正確地掌握基本知識,那介紹更進階的東西(如碰撞檢測和物理動作)也是沒有意義的。讓我們從基礎開始吧!
你的第一個SpriteKit專案
學習一個framework最好的方法就是使用它。所以,現在來創建我們第一個SpriteKit項目。請先啟動Xcode並從iOS項目選單中選擇Game的模板(template),如下所示:
下一步進入項目設定:
在這裡,最重要的事情是選擇Game Technology項目字段-確認你在對應的選單中選擇了SpriteKit:
現在請儲存你的項目,完成 – 該是整理它的時候了!
整理你的項目
遊戲模板會提供樣板程序代碼便利你的初始工作,但讀者將從頭開始編寫所有內容,因此,請清除GameScene.swift和GameViewController.swift文件中的所有內容。
GameScene.sks和Actions.sks文件可幫助你更直觀的設計場景和動作。但是,先以編程方式創建它們會更容易理解,所以現在請先刪除這兩個文件 – 你將在另一個教程學習如何使用SpriteKit編輯器。請確保在提示時將文件永久移動到垃圾桶,而不是僅僅從項目中刪除它們的引用:
這些就是我們前期需要做的項目整理工作 – 編寫程序代碼的時候到了!
建立視圖控制器
因為我們已經清空GameViewController.swift,我們現在將從頭開始創建視圖控制器(view controller),將以下這段程序代碼添加到GameViewController.swift文件,開始我們的編碼動作:
import SpriteKit class GameViewController: UIViewController { }
這裡我們import SpriteKit的框架進來,並且進行類別宣告,該類別是一個標準的視圖控制器,它的主要作用是在控制器的視圖加載後呈現遊戲場景,因此將viewDidLoad方法添加到class裡面:
override func viewDidLoad { let scene = GameScene(size: view.frame.size) let skView = view as! SKView skView.presentScene(scene) }
讓我們一步一步介紹上述程序代碼的意義:
Line #1 – 你覆寫了視圖控制器裡面的viewDidLoad方法 – 它在視圖控制器加載到內存後立即運行。
Line #2 – 你使用GameScene類別內指定的初始化方法(designated initialiser)創建場景:它貼滿整個屏幕畫面,因此它與控制器視圖的frame相同大小。
注意:此時Xcode會顯示錯誤:Use of unresolved identifier “GameScene”,因為您尚未實現GameScene類別,接下來我們會盡快解決這個問題。
Line #3 – 強制將控制器的視圖轉型為SpriteKit視圖 – 這是唯一呈現SpriteKit內容的視圖類型。在這種情況下,因為我們正在使用遊戲模板,所以轉型動作大多會是成功的,因此將控制器視圖的類別預設為SKView,而不是storyboard裡面的UIView。
Line #4 – 在屏幕畫面上呈現遊戲場景(scene)。在一個完整的遊戲中,你將透過轉換來呈現多個場景,但現在為了保持項目的簡潔,將只會使用一個。
以上為視圖控制器的設置作業。 現在,讓我們繼續創建一個場景。
創建一個場景
同樣,我們將GameScene.swift文件的內容清空。我將在這裡教你如何從頭開始創建它。請先將以下程序代碼添加到GameScene.swift文件中,開始我們的建置作業:
import SpriteKit class GameScene: SKScene { }
你將SpriteKit框架import進來,並且定義了類別,它是標準SpriteKit場景的子類別(即SKScene)。前一個錯誤已經被修復,所以構建和運行項目,查看你場景的呈現結果:
注意:我使用iPhone 5s仿真器來運行這個項目,讀者可以隨意挑選你最喜歡的仿真器。
場景看起來是空的,除了本身做為場景之外,它沒有其他節點連接到它。Okay,現在停止這個應用程序,並返回到編輯器,添加第一個節點到這個場景!
替場景添加一個節點
第一個節點只是一個簡單的標籤(label)。在GameScene類別中,宣告一個名為label的label屬性:
let label = SKLabelNode(text: "Hello SpriteKit!")
當遊戲需要在某一時點顯示文本(text),SpriteKit提供了一個類別名為SKLabelNode來顯示文本卷標。上面的代碼只是實例化一個SKLabelNode對象,並將其初始字符串設置為Hello SpriteKit!,但是,除非在視圖控制器呈現場景時,將其添加到場景的節點樹,否則不會發生任何事情。換句話說,您必須提供額外的實作,才能在屏幕畫面上顯示卷標。
現在向類別添加一個名為didMove(to:)的新方法:
override func didMove(to view: SKView) { addChild(label) }
我們覆寫場景的didMove(to:)方法。它是在場景由其相應的視圖呈現之後立即運行的方法。在方法實作中,我們調用addChild方法將標籤做為子節點添加到場景的節點樹。
現在,再次運行這個應用程序,你應該會在屏幕畫面上看到卷標:
但是這邊出現一個問題:這個標籤被切掉了,因為它的位置默認值被設置為(0,0)。
好的,現在讓我們繼續本教程的最後一部分,更改一些設定讓卷標能置中顯示。
將標籤置中
在標籤添加到場景之前,將下列這一行程序代碼添加到didMove(to:)方法中:
label.position = CGPoint(x: view.frame.width / 2, y: view.frame.height / 2)
你可以使用視圖的寬度和高度來確定標籤的座標,藉此將其放置在畫面中心。屏幕的尺寸不是寫死的,所以標籤可以正確放置在所有iPhone仿真器上。
運行並且瞧瞧畫面的顯示結果!卷標應該會在屏幕上完美呈現。
除了卷標的position屬性,還有很多屬性可以調整更改卷標樣式。舉例來說,你可以更改其字體大小,類型和顏色,如下所示:
label.fontSize = 45 label.fontColor = SKColor.yellow label.fontName = "Avenir"
結論
本教程的第一部分已經接近尾聲 – 讀者已經在SpriteKit使用場景、節點、標籤和座標點,讓卷標在屏幕畫面上居中顯示。 在下一部分中,你將使用手勢辨識器(gesture recognizers)和動作(actions),移動、縮放和旋轉標籤。敬請關注,在此期間如果讀者有任何問題或問題,請讓我知道。
以供參考,讀者可以在GitHub下載完整專案。