Quick-Cocos2d-x初學者遊戲教程(六) --------------------- 遊戲邏輯

Quick-Cocos2d-x初學者遊戲教程(六)

上一章我 們介紹了開發中會用到的輔助工具,並建立了 GameScene 場景,接下來這章咱們將繼續 GameScene 的傳(bai)奇(bi)。不過在開始編寫 GameScene 場景的代碼以前,咱們仍是先來明確一下游戲的功能和實現方法。這樣能夠幫咱們更好的理解並設計邏輯。下面是總結出的結論:css

  1. 在 GameScene 場景中,咱們將建立一個飛行的娃娃角色,這個角色是遊戲的惟一主角。遊戲初始狀態下,這個角色有滿滿的生命值,但隨着時間的推移,生命值會不斷的減小。這裏生命值咱們能夠以進度條的形式來展現它的多少和增減。
  2. 遊戲 GameScene 場景有不止一層的滾動背景,每層的背景滾動速率不一,這樣能夠產生立體的滾動效果。娃娃位置不動,讓背景不停的滾動,能夠產生娃娃在向前飛行的視覺感覺。
  3. 在滾動過程當中屏幕上會時不時的出現一些障礙物和能夠增長生命值的獎勵品,當娃娃碰到障礙物時,生命值減小;碰到獎勵品時,生命值增長。
  4. 當觸碰屏幕時,娃娃將向上升至必定的高度;當不觸碰屏幕時,它將向下掉落。掉落到地板時會扣除相應的生命值。因此玩家必須在按與不按之間保持必定的平衡,一方面躲避障礙物並避免觸碰地板,另外一方面爭取多吃一點獎勵品,這樣才能讓娃娃順利地到達終點。
  5. 本場景咱們將用物理引擎來模擬整個飛行世界,這樣遊戲主角的飛行問題(漂浮狀態),以及它與障礙物/獎勵品之間的碰撞檢測就很容易實現了。

GameScene 的背景

爲了產生立體的滾動視覺效果,咱們決定用四層不一樣的背景來實現這一效果(怕累死的,能夠偷懶)。固然,這裏層的概念不一樣於引擎中的層(cc.Layer),它只是一個普通的副詞而已。html

  • 首先,最底層是一張固定不動的布幕背景;
  • 其次,我將在布幕背景的上層添加一層遠景背景,該背景將會以較慢的速度向左滾動;
  • 而後,在遠景背景的上層咱們又會添加一層近景背景,該背景將會以較快的速度向左滾動;
  • 最後,在最上層,咱們將放置一層以更快速度向左滾動的背景,遊戲的障礙物和獎勵品都會在該層背景上。因此這層背景咱們將用 TliedMap 編輯器來製做,也就是用 TMX 文件來建立。

亂入一個知識點:遊戲中元素的層級關係由 z-order 屬性來決定,咱們能夠經過設置元素的z-order值來控制元素之間的渲染順序。默認狀況下,全部元素的 z-order 爲0,因此當遊戲元素沒有指定z-order值時,遊戲中的元素將按添加順序來顯示。故此,咱們在添加遊戲背景或其餘元素時,應該要注意下它們的添加順序 或 z-order 值,不要出現遮擋的現象。api

建立BackgroundLayer背景層

爲了讓代碼結構更加清晰,接下來咱們將爲 GameScene 場景建立一個背景層,而後把以上的四層背景圖都添加到該層上。
frameapp

因此,咱們在 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 局部型的類。工具

把背景層添加到GameScene場景

BackgroundLayer.lua 文件是個單獨的模塊文件,若是咱們想要引用它,那咱們須要把它加載到項目中來。ui

一般,載入文件到 Quick 項目可使用如下的兩種方式:lua

  1. 經過require()方法,該方法會搜索指定的目錄,並加載文件。
  2. 經過import()方法,該方法用於處理require同目錄下其餘模塊,在模塊名前加.。

它們的詳細用法參見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] 後面。

gs

在此以後,須要添加不斷執行 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 後,幀事件纔會被觸發。

此時咱們再用一樣的方法添加近景背景(讓它每次移動的距離大一些),運行遊戲時,屏幕上就會出現滾循環移動的背景了。

bg

注:以上截圖不是循環的。

最上層的TMX背景

背景層中還有一個重要的滾動項,那就是容納了障礙物和獎勵品的 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 文件後一併上傳。

相關文章
相關標籤/搜索