上一章我 們介紹了開發中會用到的輔助工具,並建立了 GameScene 場景,接下來這章咱們將繼續 GameScene 的傳(bai)奇(bi)。不過在開始編寫 GameScene 場景的代碼以前,咱們仍是先來明確一下游戲的功能和實現方法。這樣能夠幫咱們更好的理解並設計邏輯。下面是總結出的結論:css
爲了產生立體的滾動視覺效果,咱們決定用四層不一樣的背景來實現這一效果(怕累死的,能夠偷懶)。固然,這裏層的概念不一樣於引擎中的層(cc.Layer),它只是一個普通的副詞而已。html
亂入一個知識點:遊戲中元素的層級關係由 z-order 屬性來決定,咱們能夠經過設置元素的z-order值來控制元素之間的渲染順序。默認狀況下,全部元素的 z-order 爲0,因此當遊戲元素沒有指定z-order值時,遊戲中的元素將按添加順序來顯示。故此,咱們在添加遊戲背景或其餘元素時,應該要注意下它們的添加順序 或 z-order 值,不要出現遮擋的現象。api
爲了讓代碼結構更加清晰,接下來咱們將爲 GameScene 場景建立一個背景層,而後把以上的四層背景圖都添加到該層上。
app
因此,咱們在 src/app 目錄下新建了一個layers 文件夾,而後再新建了一個 BackgroundLayer.lua 文件,並把它保存到 src/app/layers 目錄下。框架
如下是建立空白 BackgroundLayer 層的代碼:編輯器
1
2
3
4
5
6
7
8
|
BackgroundLayer =
class
(
"BackgroundLayer"
,function()
return
display.newLayer()
end)
function BackgroundLayer:ctor()
end
return
BackgroundLayer
|
display.newLayer()方法能建立並返回一個 cc.Layer 層對象。函數
注意:由於咱們將在其餘(GameScene.lua)文件中調用 BackgroundLayer 類,因此在建立 BackgroundLayer 類時,咱們並無像建立 GameScene 同樣把它定義爲 local 局部型的類。工具
BackgroundLayer.lua 文件是個單獨的模塊文件,若是咱們想要引用它,那咱們須要把它加載到項目中來。ui
一般,載入文件到 Quick 項目可使用如下的兩種方式:lua
它們的詳細用法參見API。
這裏,咱們載入 BackgroundLayer 模塊用 require 方法。在 MyApp.lua 中加入以下的函數:
1
|
require(
"app.layers.BackgroundLayer"
)
|
這樣就把咱們定義的 BackgroundLayer 類引入到了quick項目中,以後,咱們就能夠在任何地方引用這個 BackgroundLayer 模塊了。
接下來咱們來把 BackgroundLayer 層加入到 GameScene 場景中。
1
2
3
4
5
|
function GameScene:ctor()
self.backgroundLayer = BackgroundLayer.
new
()
:addTo(self)
end
|
這裏調用BackgroundLayer.new()
方法實例化了一個 BackgroundLayer 對象,並把它加入到場景。這樣 GameScene 場景中就有一層空白的 BackgroundLayer 層了。
框架整好之後,下面咱們來向層容器裏面塞東西。
回到 BackgroundLayer 文件,下面咱們添加以下的一段函數來爲 BackgroundLayer 層添加最底層的布幕背景,這裏添加固定不動的布幕背景就如添加普通精靈。
1
2
3
4
5
6
|
function BackgroundLayer:createBackgrounds()
-- 建立布幕背景
local bg = display.newSprite(
"image/bj1.jpg"
)
:pos(display.cx, display.cy)
:addTo(self, -4)
end
|
addTo方法中能夠指定遊戲元素的 z-order 值,本教程中,咱們把布幕背景的z-order設置爲-4,確保它位於場景的最下層(固然,這要確保該層中不能有比布幕背景的 z-order 值還小的元素)。
遠景背景和近景背景有着共同的特徵,它們都會以必定的速度向左循環移動。因此這裏咱們以遠景背景爲例,說明下它們的實現過程。
首先,咱們添加兩張首尾能夠拼接的圖片來表示滾動的遠景背景圖。
在BackgroundLayer:createBackgrounds()
方法中加入以下的代碼來添加遠景背景圖:
1
2
3
4
5
6
7
8
9
10
|
-- 建立遠景背景
local bg1 = display.newSprite(
"image/b2.png"
)
:align(display.BOTTOM_LEFT, display.left , display.bottom + 10)
:addTo(self, -3)
local bg2 = display.newSprite(
"image/b2.png"
)
:align(display.BOTTOM_LEFT, display.left + bg1:getContentSize().width, display.bottom + 10)
:addTo(self, -3)
table.insert(self.distanceBg, bg1) -- 把建立的bg1插入到了 self.distanceBg 中
table.insert(self.distanceBg, bg2) -- 把建立的bg2插入到了 self.distanceBg 中
|
其中 self.distanceBg 是一個 table 類型的值,它的定義咱們放在 ctor 函數中。
1
|
self.distanceBg = {}
|
實現滾動背景,須要作的就是不斷的改變背景圖片貼圖橫座標,而且不斷的刷新位置。因此咱們定義了一個滾動背景的函數scrollBackgrounds()。
1
2
3
4
5
6
7
8
9
10
11
12
|
function BackgroundLayer:scrollBackgrounds(dt)
if
self.distanceBg[2]:getPositionX() <= 0 then
self.distanceBg[1]:setPositionX(0)
end
local x1 = self.distanceBg[1]:getPositionX() - 50*dt -- 50*dt 至關於速度
local x2 = x1 + self.distanceBg[1]:getContentSize().width
self.distanceBg[1]:setPositionX(x1)
self.distanceBg[2]:setPositionX(x2)
end
|
以上的這段函數的做用就是讓 self.distanceBg[1]
和 self.distanceBg[2]
的 X 座標都向左移動 50 * dt (dt是時間間隔,兩幀之間的時間間隔)個單位,self.distanceBg[2]
緊接在 self.distanceBg[1]
後面。
在此以後,須要添加不斷執行 scrollBackgrounds() 函數的方法,以確保遠景背景不斷的向左移動。使用過 Cocos2d-x 的童鞋應該知道,Cocos2d-x 中能夠經過重載 update 函數在每幀刷新的時候執行本身須要的一些操做。在 Quick 框架中,咱們把這種事件叫作幀事件,意思是每幀刷新時都會執行的事件。
幀事件在遊戲中常常用來更新遊戲中的數據。下面咱們將在 ctor() 函數中加入這種幀事件,用以更新背景圖的座標。代碼以下:
1
2
3
4
5
6
7
8
9
10
11
|
function BackgroundLayer:ctor()
self.distanceBg = {}
self.nearbyBg = {}
self.tiledMapBg = {}
self:createBackgrounds()
self:addNodeEventListener(cc.NODE_ENTER_FRAME_EVENT, handler(self, self.scrollBackgrounds))
self:scheduleUpdate()
end
|
其中,addNodeEventListener 方法用於註冊幀事件,scheduleUpdate 方法則啓用了幀事件,只有調用了 scheduleUpdate 後,幀事件纔會被觸發。
此時咱們再用一樣的方法添加近景背景(讓它每次移動的距離大一些),運行遊戲時,屏幕上就會出現滾循環移動的背景了。
注:以上截圖不是循環的。
背景層中還有一個重要的滾動項,那就是容納了障礙物和獎勵品的 TMX 類型的背景。
前面章節中咱們已經提到過,TiledMap 編輯器能把單個的圖塊拼接成一幅完整的地圖,而它的最終產物就是 TMX 文件。這裏咱們也不要把它想的有多複雜,其實說白了,渲染出來就是一張破圖而已。和 png,jpg的圖片精靈外形無明顯差別。
因此它滾動的原理和遠/近景背景滾動的原理差很少,只不過,它不循環。咱們能夠用一個以上的 TMX 文件來實現滾動,當最後一個 TMX 文件恰好顯示完的時候遊戲就結束。這裏考慮到後續的碰撞檢測,因此咱們只用一個 TMX 文件實現滾動。
載入 TMX 文件的代碼以下,添加的位置依舊在 createBackgrounds 方法中。
1
2
3
|
self.map = cc.TMXTiledMap:create(
"image/map.tmx"
)
:align(display.BOTTOM_LEFT, display.left, display.bottom)
:addTo(self, -1)
|
讓地圖文件滾動的代碼以下:
1
2
3
4
5
6
|
if
self.map:getPositionX() <= display.width - self.map:getContentSize().width then
self:unscheduleUpdate() -- 禁用幀事件,中止整個背景層滾動
end
local x5 = self.map:getPositionX() - 130*dt
self.map:setPositionX(x5)
|
好了,本週的教程就算完成了,這裏咱們的 tmx 文件是在下暫時隨便建立的一個,下一章咱們會詳細地講解如何製做 tmx 文件。
另外,關於本遊戲的資源咱們將會在下章好好製做 tmx 文件後一併上傳。