本節書摘來自異步社群《ios和tvos 2d遊戲開發教程》一書中的第1章,第1.2節顯示精靈,作者 【美】raywenderlich.com教程開發組,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
1.2 顯示精靈
在制作2d遊戲的時候,通常要将表示遊戲的各種要素的圖像放置到螢幕上,如英雄、敵人、子彈等,如圖1-18所示。這些圖像中的每一個,都叫做精靈(sprite)。
圖1-18
sprite kit有一個叫做skspritenode的特殊的類,它使得建立和使用精靈更為容易。我們就是使用這個類來為遊戲添加所有的精靈的。讓我們來嘗試一下。
1.2.1 建立精靈
打開gamescene.swift,給didmovetoview()添加如下的一行,就放在設定了背景顔色之後:
let background = skspritenode(imagenamed: "background1")
不需要傳入該圖像的擴充名,sprite kit将自動為你确定它。
編譯并運作,現在先忽略警告。好了,你認為這很簡單吧,但是現在,你還是會看到一個空白的界面,怎麼會這樣呢?
1.2.2 把精靈加到場景
這确實很簡單。因為在你把精靈作為場景的一個子節點或者場景的一個後代節點添加之前,精靈是不會顯示在螢幕上的。
要做到這一點,在上面的那一行代碼之後,添加如下這行代碼:
addchild(background)
我們稍後将學習節點和場景。現在,再次編譯并運作,你将會看到背景的一部分出現在螢幕的左下方,如圖1-19所示。
圖1-19
顯然,這還不是我們想要的樣子。要讓背景處于正确的位置,必須要設定其位置。
1.2.3 定位精靈
預設情況下,sprite kit将精靈放置在(0, 0),這在sprite kit中表示螢幕左下方的位置。注意,ios中的坐标系統和uikit的坐标系統不同,在ios中,(0, 0)表示左上方。
嘗試設定position屬性,進而将背景放置到其他的某個位置。添加如下的一行代碼,放在調用addchild(background)之前:
background.position = cgpoint(x: size.width/2, y: size.height/2)
這裡,我們将背景設定到了螢幕的中央。即便是這樣一行簡單的代碼,也有重要的4點需要了解:
1.position屬性的類型是cgpoint,這是一個簡單的結構體,包含了x和y部分。
2.可以很容易地使用如下所示的初始化程式來建立一個cgpoint。
3.既然在一個skscene子類中編寫這段代碼,任何時候,都可以使用size屬性來通路場景的大小。size屬性的類型是cgsize,這是和cgpoint一樣的一個簡單結構體,包含了width和height部分。
4.一個精靈的位置在其父節點的坐标空間之中,在這個例子中,其父節點就是場景本身。我們将在第5章中更詳細地介紹這一點。
編譯并運作,現在,背景完全可見了,如圖1-20所示。
注意
你可能注意到了,在iphone裝置上,是無法看到整個背景的,其頂部和底部的一部分重疊了。這是因為這款遊戲設計為在ipad和iphone上都可以工作,正如本章前面的1.1.1小節“通用app支援”所介紹的那樣。
圖1-20
1.2.4 設定精靈的錨點
設定背景精靈的位置,意味着把精靈的中心點設定為該位置。這就說明了為什麼在此之前我們隻能夠看到背景的上半部分。在我們設定精靈的位置之前,其預設位置在(0, 0),這會将精靈的中心放置在螢幕的左下角,是以,我們隻能夠看到精靈的上半部分。
可以通過設定精靈的錨點來改變這一行為。把錨點當做是“精靈中的一個點,通過這個點将精靈固定在一個特定的位置”。圖1-21展示了放置在螢幕中心的精靈,但是它們使用了不同的錨點。
圖1-21
要看看這是如何工作的,找到将背景位置設定為螢幕中心的那一行代碼,并且用如下的代碼替換它。
cgpoint.zero是的(0, 0)一種友善的簡寫。這裡,我們将精靈的錨點設定為(0, 0),以便将其精靈的左下角固定到所設定的位置,也就是(0, 0)。
編譯并運作,現在圖像仍然在正确的位置,如圖1-22所示。
圖1-22
這之是以有效,是因為我們将背景圖像的左下角固定到了場景的左下角。
這裡,為了學習的目的,我們修改了背景的錨點。然而,通常可以将錨點保留為其預設值(0.5, 0.5),除非你有特定的需求,要讓精靈圍繞一個特定的點旋轉,我們将在下一小節給出這樣的一個例子。
是以,簡而言之,當設定精靈的位置的時候,預設情況下,你将設定精靈的中心點的位置。
1.2.5 旋轉精靈
要旋轉一個精靈,直接設定其zrotation屬性。在調用addchild()之前,添加如下的這行代碼,進而嘗試一下旋轉背景精靈。
background.zrotation = cgfloat(m_pi) / 8
旋轉值以弧度為機關,這是用來度量角的一個機關。這個示例将精靈旋轉π/ 8個弧度,這等于22.5°。還要注意将m_pi(這是一個double類型)轉換為一個cgfloat。之是以要這麼做,是因為zrotation需要一個cgfloat,而swift不會像其他的語言那樣,自動地在這些類型之間轉換。
我發現用角度來考慮旋轉比用弧度要容易,不知道你怎麼看。在本書稍後,我們将建立一個輔助程式,來實作角度和弧度之間的轉換。
編譯并運作,檢視一下旋轉後的背景精靈,如圖1-23所示。
圖1-23
這展示了重要的一點,精靈是圍繞其錨點旋轉的。由于我們将背景精靈的錨點設定為(0, 0),背景将圍繞着其左下角旋轉。
記住,在iphone上,圖像的左下角實際上在螢幕之外。如果不确定為什麼這樣,請參考本章前面的1.1.1小節“通用app支援”。
嘗試一下圍繞着精靈的中心點來旋轉精靈。将設定精靈位置和錨點的代碼行,替換為如下的代 碼行:
圖1-24
了解了這些知識點就很好了。但是對于zombie conga,我們并不想要一個旋轉後的背景,是以,注釋掉如下這行代碼:
如果對于在遊戲中什麼時候需要修改錨點還心存疑惑,假想一下我們要建立這樣一個角色,其身體是由不同的精靈組成的,而每個精靈分别表示腦袋、身體、左胳膊、右胳膊、左腿到右腿,等等,如圖1-25所示。
圖1-25
如果需要繞着這個角色的關節來旋轉它的身體的各個部分,那麼對于每一個精靈,都必須要修改其錨點。
再一次強調,通常應該保持錨點為預設位置,除非你有特殊的需求,就像圖1-25中所給出的例子那樣。
1.2.6 擷取精靈的大小
有時候,當操作精靈的時候,我們想要知道它有多大。精靈的大小預設為圖像的大小。在sprite kit中,表示圖像的類叫做材質。
在addchild()調用的後面,添加如下的代碼行,以擷取背景的大小并将其列印到控制台:
編譯并運作,在控制台的輸出中,應該會看到如下所示的内容:
有時候,通過程式設計(就像上面那樣)而不是使用直接編碼的數字來擷取精靈的大小,這是很有用的。你的代碼将會健壯很多,并且更易于修改。
1.2.7 精靈和節點
在前面,我們學習了如何讓精靈出現在螢幕上,這需要将其作為場景的一個子節點或者一個後代節點添加。本小節将更深入地介紹節點的概念。
在sprite kit中,螢幕上所顯示的一切内容,都派生自一個叫做sknode的類。場景類(skscene)和精靈類(skspritenode)都派生自sknode,如圖1-26所示。
skspritenode的很多功能都是繼承自sknode的。例如,position和zrotation屬性都是派生自sknode的,而并非skspritenode自己所特有的。這意味着,你可以對場景本身或者派生自sknode的任何對象做相同的事情,就像能夠設定一個精靈的位置或旋轉精靈一樣。
可以将出現在螢幕上的一切内容綜合起來,看做是節點組成的一幅圖,這通常稱之為場景圖。例如,假設zombie conga遊戲中隻有一個僵屍、兩隻小貓和一個貓女士,其場景圖如圖1-27所示。
圖1-27
我們将在第5章中更詳細地了解節點以及能對節點做的事情。現在,我們将把精靈作為場景的直接子節點添加。
1.2.8 節點和z位置
每個節點都有一個名為zposition的屬性,它的預設值為0。每個節點都會按照其子節點的z位置,從低到高依次繪制其子節點。
在本章前面,我們給gameviewcontroller.swift添加了如下這一行:
如果ignoressiblingorder為true,對于擁有相同的zposition屬性的每一個子節點,sprite kit将不保證按照何種順序來繪制它們。
如果ignoressiblingorder為false,對于擁有相同的zposition屬性的每一個子節點,sprite kit将按照它們添加到父節點的順序來繪制它們。
通常,将這個屬性設定為true是較好的做法,因為這允許sprite kit在幕後進行性能優化,以使得你的遊戲運作得更快。
然而,如果不小心的話,将這個屬性設定為true也可能會引發問題。例如,如果把和背景擁有相同的zposition的一個僵屍添加到了場景中(如果還是把僵屍和背景的zpositon都保留為預設的0的話,就可能會發生這種情況),sprite kit可能會把背景繪制于僵屍之上,這會蓋住了僵屍而讓玩家看不到它。并且如果僵屍很吓人的話,想象一下看不到它的情況。
為了避免這種情況,我們将背景的zposition設定為-1。通過這種方式,sprite kit将會先繪制它,然後再繪制添加到場景中的任何其他内容(這些内容的預設的zposition為0)。
1.2.9 最後修整
本章的内容到此為止了。正如你所看到的,隻需要三四行代碼就可以把精靈添加到場景中。步驟如下:
1.建立精靈。
2.放置精靈。
3.可選地設定zposition。
4.把精靈添加到場景圖中。
現在,我們來把僵屍添加到場景中,以測試一下新學的知識。