前面的話
本文將詳細介紹 cocos 場景制作流程
節點和組件
Cocos Creator 的工作流程是以組件式開發為核心的,組件式架構也稱作組件-實體系統,簡單的說,就是以組合而非繼承的方式進行實體的構建
在 Cocos Creator 中,節點(Node)是承載組件的實體,通過將具有各種功能的組件(Component)掛載到節點上,來讓節點具有各式各樣的表現和功能
要最快速的獲得一個具有特定功能的節點,可以通過層級管理器左上角的創建節點按鈕
以創建一個最簡單的 Sprite(精靈)節點為例,點擊創建節點按鈕后選擇創建渲染節點/Sprite(精靈)

之后就可以在場景編輯器和層級管理器中看到新添加的 Sprite 節點了。新節點命名為 New Sprite
,表示這是一個主要由 Sprite 組件負責提供功能的節點
選中剛才創建的 New Sprite
節點,可以看到屬性檢查器中的顯示

屬性檢查器中以 Node
標題開始的部分就是節點的屬性,節點屬性包括了節點的位置、旋轉、縮放、尺寸等變換信息和錨點、顏色、不透明度等其他信息
接下來以 Sprite
標題開始的部分就是 Sprite 組件的屬性,在 2D 游戲中,Sprite 組件負責游戲中絕大部分圖像的渲染。Sprite 組件最主要的屬性就是 Sprite Frame
,可以在這個屬性指定 Sprite 在游戲中渲染的圖像文件
下面從資源管理器中拖拽任意一張圖片資源到屬性檢查器的 Sprite Frame
屬性中

剛才的默認 Sprite 圖片變成了指定的圖片,這就是 Sprite 組件的作用:渲染圖片
組件式的結構是以組合方式來實現功能的擴展的,下圖中就展示了節點和 Sprite 組件的組合

節點的顏色(Color)屬性和不透明度(Opacity)屬性直接影響了 Sprite 組件對圖片的渲染。顏色和不透明度同樣會影響文字(Label)這樣的渲染組件的顯示。 這兩個屬性會和渲染組件本身的渲染內容進行相乘,來決定每個像素渲染時的顏色和不透明度。此外不透明度(Opacity)屬性還會作用於子節點,可以通過修改父節點的 Opacity 輕松實現一組節點內容的淡入淡出效果
值得注意的是,一個節點上只能添加一個渲染組件,渲染組件包括 Sprite(精靈), Label(文字),Particle(粒子)等
坐標系
在 iOS, Android, Windows Phone 等平台用原生 SDK 開發應用時使用的是標准屏幕坐標系,原點為屏幕左上角,x 向右,y 向下。
Cocos2d-x 坐標系和 OpenGL 坐標系一樣,原點為屏幕左下角,x 向右,y 向上

世界坐標系也叫做絕對坐標系,在 Cocos Creator 游戲開發中表示場景空間內的統一坐標體系,「世界」就用來表示游戲場景
本地坐標系也叫相對坐標系,是和節點相關聯的坐標系。每個節點都有獨立的坐標系,當節點移動或改變方向時,和該節點關聯的坐標系將隨之移動或改變方向
Cocos Creator 中的節點(Node)之間可以有父子關系的層級結構,修改節點的位置(Position)屬性設定的節點位置是該節點相對於父節點的本地坐標系而非世界坐標系。最后在繪制整個場景時 Cocos Creator 會把這些節點的本地坐標映射成世界坐標系坐標
錨點(Anchor)決定了節點以自身約束框中的哪一個點作為整個節點的位置。選中節點后看到變換工具出現的位置就是節點的錨點位置
錨點由 anchorX
和 anchorY
兩個值表示,他們是通過節點尺寸計算錨點位置的乘數因子,范圍都是 0 ~ 1
之間。(0.5, 0.5)
表示錨點位於節點長度乘 0.5 和寬度乘 0.5 的地方,即節點的中心。錨點屬性設為 (0, 0)
時,錨點位於節點本地坐標系的初始原點位置,也就是節點約束框的左下角。錨點位置確定后,所有子節點就會以錨點所在位置作為坐標系原點
節點包括四個主要的變換屬性
1、位置(position)
位置(Position) 由 x
和 y
兩個屬性組成,分別規定了節點在當前坐標系 x 軸和 y 軸上的坐標。
2、旋轉(rotation)
旋轉屬性只有一個值,表示節點當前的旋轉角度。角度值為正時,節點順時針旋轉,角度值為負時,節點逆時針旋轉
3、縮放(scale)
縮放屬性也是一組乘數因子,由 scaleX
和 scaleY
兩個值組成,分別表示節點在 x 軸和 y 軸的縮放倍率
4、尺寸(size)
尺寸屬性由 Width
(寬度)和 Height
(高度)兩個值組成,用來規定節點的約束框大小。對於 Sprite 節點來說,約束框的大小也就相當於顯示圖像的大小
【坐標變換】
通過getPosition()獲得的值是本地坐標系的值,即相對於其直接父級的坐標值。比如,父級坐標為(100, 0),子級坐標為(30, 0),而實際上子級坐標是(130, 0)。
要獲得子級的真實坐標,需要先將子級坐標基於其直接父級轉換成世界坐標
item.parent.convertToWorldSpaceAR(item.getPosition()))
然后,再將得到的子級世界坐標轉換到實際坐標系下,如轉換到this.node坐標系下
this.node.convertToNodeSpaceAR(item.parent.convertToWorldSpaceAR(item.getPosition()))
節點層級
當場景中的元素越來越多時,需要通過節點層級來將節點按照邏輯功能歸類,並按需要排列顯示順序
每個視覺元素都是一個節點,通常不會把所有節點平鋪在場景上,而是會按照一定的分類和次序組織成如下圖所示的節點樹

節點樹中由箭頭連接的兩個節點之間就是父子關系,把顯示在上面的叫做父節點,下面的叫子節點。在層級管理器中,上面的節點樹就會是這個樣子

在游戲中經常需要控制復雜的玩家角色,這種角色通常不會只由單個節點組成,下面來看看下面這張圖里的英雄角色,就由三個不同的部分組成

將英雄角色的 Sprite 圖像顯示和幀動畫組件放在 body
節點上,然后需要跟隨角色移動的陰影 Sprite 單獨拿出來作為 shadow
節點。最后把負責生命值顯示的進度條作為一組獨立功能的節點,形成自己的迷你節點樹 HPBar
上面的例子就是典型的根據邏輯需要來組織節點關系,可以根據游戲邏輯操作英雄角色節點的動畫播放、左右翻轉;根據角色當前血量訪問 HPBar
節點來更新生命值顯示;最后他們共同的父節點 player
用於控制角色的移動,並且可以作為一個整體被添加到其他場景節點中
在層級管理器中會按照節點排列順序依次渲染,也就是顯示在列表上面的節點會被下面的節點遮蓋住。body
節點在列表里出現在下面,因此實際渲染時會擋住 shadow
節點
父節點永遠是出現在子節點上面的,因此子節點永遠都會遮蓋住父節點
雖然父節點可以用來組織邏輯關系甚至是當做承載子節點的容器,但節點數量過多時,場景加載速度會受影響,因此在制作場景時應該避免出現大量無意義的節點,應該盡可能合並相同功能的節點
場景編輯器
Canvas 節點是推薦使用的渲染根節點,將所有渲染相關的節點都放在 Canvas 下面,這樣做有以下兩點好處:
1、Canvas 能提供多分辨率自適應的縮放功能,以 Canvas 作為渲染根節點能夠保證制作的場景在更大或更小的屏幕上都保持較好的圖像效果
2、Canvas 的默認錨點位置是 (0.5, 0.5)
,加上 Canvas 節點會根據屏幕大小自動居中顯示,所以 Canvas 下的節點會以屏幕中心作為坐標系的原點
除了有具體圖像渲染任務的節點之外,還會有一部分節點只負責掛載腳本,執行邏輯,不包含任何渲染相關內容。通常將這些節點放置在場景根層級,和 Canvas 節點並列,如下圖所示:

除了 Canvas 下的背景、菜單、玩家角色等節點之外,還將包含有游戲主邏輯組件的 Game
節點放在了和 Canvas 平行的位置上,方便協作的時候其他開發者能夠第一時間找到游戲邏輯和進行相關的數據綁定
為場景添加內容時,一般會先從層級管理器的創建節點菜單開始,也就是點擊左上角的 +
按鈕彈出的菜單。這個菜單的內容和主菜單中節點
菜單里的內容一致,都可以從幾個簡單的節點分類中選擇需要的基礎節點類型並添加到場景中。添加節點時,在層級管理器中選中的節點將成為新建節點的父節點
1、空節點
選擇創建節點菜單里的創建空節點
就能夠創建一個不包含任何組件的節點。空節點可以作為組織其他節點的容器,也可以用來掛載用戶編寫的邏輯和控制組件
2、渲染節點
創建節點菜單里下一個類別是創建渲染節點
,這里能找到像 Sprite(精靈)、Label(文字)、ParticleSystem(粒子)、Tilemap(瓦片圖)等由節點和基礎渲染組件組成的節點類型
這里的基礎渲染組件,是無法用其他組件的組合來代替的,因此單獨歸為渲染類別。要注意每個節點上只能添加一個渲染組件,重復添加會導致報錯。但是可以通過將不同渲染節點組合起來的方式實現更復雜的界面控件,比如下面 UI 類中的很多控件節點
3、UI節點
從創建節點菜單中的創建 UI 節點
類別里可以創建包括 Button(按鈕)、Widget(對齊掛件)、Layout(布局)、ScrollView(滾動視圖)、EditBox(輸入框)等節點在內的常用 UI 控件。UI 節點大部分都是由渲染節點組合而成的,比如通過菜單創建的 Button 節點,就包含了一個包含 Button + Sprite 組件的按鈕背景節點,加上一個包含 Label 組件的標簽節點