Laya實戰-打地鼠JS版本的ES6重構

cheneyweb發表於2018-07-15

前言

在上一篇文章《從零開始製作微信小遊戲-彈一弾》中,我使用了純原生的Canvas搭配Matter物理引擎,製作了一個彈一弾的微信小遊戲,在其文末我提到了未來會寫一篇使用專業遊戲引擎製作H5遊戲的文章

這一篇文章就是這個目的。目前國內主流成熟的H5遊戲引擎有兩個,分別是Laya和Egret,其中白鷺(Egret)釋出時間較早,發展到現在已經很成熟,有相當多的商業遊戲案例。Laya是後來崛起的H5遊戲引擎,號稱效能速度最快,也有了很多商業遊戲案例。實際上關於兩者對比的文章網際網路上比比皆是,但其實兩者支援的語言和功能都差不多,無論選擇哪一個都可以

演示

hitmole-demo.gif

hitmole-qrcode.png

可以瀏覽器/微信掃碼體驗試玩,也可以直接訪問 cheneyweb.github.io/laya-hitmol… 進行遊戲體驗

引擎

本文選擇了Laya,主要出於以下幾點考慮

  • LayaAir更輕量,一個IDE幾乎涵蓋了H5遊戲開發的所有支撐功能
  • Laya引擎推出時間較晚,參考了很多引擎的設計優點,整體API設計簡潔高效
  • 支援一鍵匯出微信小程式
  • Laya官方文件詳細且全面,論壇活躍度高,且有詳細的視訊教程,本文的案例就是基於其視訊教程《Laya引擎官方實戰教學—JS版本打地鼠》分解重構還原的

引擎與原生

其實遊戲引擎在國外已經成熟使用很多年了,但是國內H5遊戲採用引擎開發一直沒有大面積鋪開,很大原因上是因為大部分前端遊戲入門者,如果沒有專門指引和接受過遊戲開發的系統化學習,面對遊戲引擎使用,是相當困難的一件事情

從最簡單的角度分析,我將闡述對比原生開發,採用遊戲引擎開發會有哪些不同和優勢

  • 視覺化圖片/音效/動畫/特效等資源載入和調整,這一點是使用遊戲引擎開發和傳統原生開發最明顯的區別,它使得遊戲開發者能關注於遊戲元素的呈現,而不是如何在遊戲中載入和使用
  • 全程式碼檔案自動管理,引用,打包,這一點使得遊戲程式開發者不需要再關心各種亂七八糟的工具引入,在Laya中,程式碼中的類檔案可以隨意使用,不需要繁瑣的引入
  • 大量封裝好的迴圈動畫API,邏輯API等等,使得遊戲編碼量大幅下降,在本文中描述的打地鼠遊戲,實際編碼量就只有兩百行左右,非常少
  • 多鍾適配支援,統一的輸入事件,使得H5遊戲只需要編寫一套互動,無論是PC瀏覽器還是手機觸控,都可以輕鬆搞定
  • 極高的開發效率,我自己的體會使用遊戲引擎開發,對比原生開發,可以提高十倍以上的效率,也就是隻有相同原生遊戲十分之一的開發時間

實踐

其實這篇文章的實踐過程很難寫,因為和我以往的文章不同,可以通過程式碼展示和分析,逐步實現。遊戲引擎的開發只有30%時間會在編碼上,剩餘的更多是在使用IDE進行遊戲設計上,這是很有意思的一點

而且在我看來,遊戲開發也是最能貫徹物件導向程式設計思想的開發,而這種思想,也恰恰是很難通過文字描述的,但是不管怎麼樣,我會盡量用簡單的方式,描述使用遊戲引擎製作一款遊戲的全流程

另外需要說明的是,Laya官方教程中,JS版本的打地鼠,是採用ES5編寫的,程式碼會有些冗餘和複雜,所以我全部採用ES6重構了一遍,看起來更加簡潔清爽

遊戲入口

任何遊戲都有入口程式,Laya遊戲的入口十分簡單,只需要初始化引擎,然後載入版本控制和資源之後,就可以啟動遊戲介面了 在本文的演示遊戲中,使用WebGL的渲染模式,效能最好,如果不支援,會自動切換Canvas以獲取最好的相容性

class LayaApp {
    constructor() {
        // 初始化引擎
        const WebGL = laya.webgl.WebGL
        Laya.init(800, 600, WebGL)
        //設定版本控制型別為使用檔名對映的方式
        Laya.ResourceVersion.type = Laya.ResourceVersion.FILENAME_VERSION
        //載入版本資訊檔案
        Laya.ResourceVersion.enable("version.json", Laya.Handler.create(this, this.beginLoad))
        // 設定stage屬性
        Laya.stage.scaleMode = Laya.Stage.SCALE_SHOWALL
        Laya.stage.alignH = Laya.Stage.ALIGN_CENTER
        Laya.stage.alignW = Laya.Stage.ALIGN_CENTER
        Laya.stage.screenMode = Laya.Stage.SCREEN_NONE
        Laya.stage.bgColor = "#ffffff"
    }
    // 載入資源
    beginLoad() {
        Laya.loader.load("res/atlas/ui.atlas", Laya.Handler.create(this, this.onLoaded), null, Laya.Loader.ATLAS)
    }
    // 載入完成回撥
    onLoaded() {
        // 啟動遊戲介面
        LayaApp.gameStartView = new GameStartView()
        Laya.stage.addChild(LayaApp.gameStartView)
    }
}

// 例項化遊戲應用
new LayaApp()
複製程式碼

以下部分描述讓我糾結了許久,因為我實在不知道用什麼方式和文字表達,如果要將遊戲的開發步驟每一步都寫出來,怕是要貼上上百張圖片和寫上比遊戲編碼多十倍的文字。我想這也是為什麼Laya官方選擇採用視訊教程的方式來指引初學者入門吧

其實本文的目的更多的是讓初學者能夠對H5遊戲引擎能夠有個大概的概念,所以以下內容就更多的是闡述H5遊戲引擎的一些強大功能特效,閱讀本文之後,再去看Laya官方的視訊教程,可能會達到事半功倍的效果

資源引用

Laya的資源管理器只需要將資原始檔放置在資源關聯路徑下,便可輕鬆載入所有資原始檔,為下一步視覺化編輯遊戲介面打下基礎,具體的IDE操作方法請參考 LayaAir IDE—資源管理器

LayaAir IDE—資源管理器.png

介面實現

在引入資原始檔之後,我們便可以隨心所欲創造我們想象的遊戲介面,首先建立UI介面,然後往UI介面上拖拽資源,接著將其佈局或安排層級,最後就是為我們需要的介面元素設定屬性。最後的這一步十分關鍵,因為這是連線視覺化設計與程式編碼的橋樑 通過var屬性或name屬性,就可以在程式碼中使用相對應的介面元素,十分便捷簡單,這是遊戲引擎極大提高生產效率的重要一步,同樣,具體IDE操作方法請參考 LayaAir IDE—UI場景編輯器

image.png

/**
 * 啟動介面類
 */
class GameStartView extends ui.GameStartUI {
    constructor() {
        super()
        // 居中顯示
        this.centerX = 0
        this.centerY = 0
        // 啟動事件
        this.startBtn.on(Laya.Event.CLICK, this, this.onStartGame)
    }
    onStartGame() {
        // 移除啟動介面
        this.removeSelf()
        // 載入遊戲介面
        if (!LayaApp.gameView) {
            LayaApp.gameView = new GameView()
        }
        LayaApp.gameView.gameStart()
        Laya.stage.addChild(LayaApp.gameView)
    }
}
複製程式碼

在這裡需要提一下的是程式碼中使用到的this.startBtn,我們可以看到的是在整個類的程式碼中都沒有定義,但其實我們卻可以直接使用!

原因就是在Laya的設計皮膚中,我們建立啟動介面時,已經為其中的啟動按鈕設定了var屬性,所以我們可以直接在程式碼中使用,而且Laya封裝了API,我們更可以進一步直接使用按鈕事件響應

看到這裡,應該都可以理解了遊戲引擎如何將設計元素與編碼邏輯相關聯,而這也只是其中的一個例子

精靈實現

遊戲中往往除了靜態介面元素,還會有很多的動畫,甚至是特效等等複雜元素,而這些通過遊戲引擎都可以做到視覺化編輯,以打地鼠中的錘子敲擊動畫為例,我們通過以下方式就可以製作一個簡單的序列幀動畫,然後通過為其設定屬性,就可以在編碼中引用 更多相關IDE操作方法可以參考 LayaAir IDE—UI頁面、粒子、動畫、指令碼新增皮膚詳解

LayaAir IDE 建立動畫.png

/**
 * 錘子類
 */
class Hammer extends ui.HammerUI {
    constructor() {
        super()
        this.visible = false
    }
    // 開始使用
    start() {
        this.visible = true
        Laya.Mouse.hide()
        Laya.stage.on(Laya.Event.MOUSE_DOWN, this, this.onMouseDown)
        Laya.stage.on(Laya.Event.MOUSE_MOVE, this, this.onMouseMove)
        this.onMouseMove()
    }
    // 結束使用
    end() {
        this.visible = false
        Laya.Mouse.show()
        Laya.stage.off(Laya.Event.MOUSE_DOWN, this, this.onMouseDown)
        Laya.stage.off(Laya.Event.MOUSE_MOVE, this, this.onMouseMove)
    }
    onMouseDown() {
        this.hit.play(0, false)
    }
    onMouseMove() {
        this.pos(Laya.stage.mouseX - this.width / 2, Laya.stage.mouseY - this.height / 2)
    }
}
複製程式碼

在這裡希望展示的是遊戲引擎對於互動API的封裝,在Laya中,所有的互動事件都有統一的API,而且十分簡潔明瞭,開發者幾乎不再需要為PC或移動裝置的互動適配而煩惱

構建釋出

最後當遊戲編碼,測試完成之後,通過IDE的一鍵釋出功能,就可以輕鬆將整個遊戲打包

LayaAir IDE—構建釋出.png

本文的專案原始碼會於文末附上,在其中會有因為限於文章篇幅沒法詳盡描繪的細節

感謝你的閱讀,希望本文能夠給你帶來幫助:)

作者:CheneyXu

Github:laya-hitmole

關於:XServer官網

相關文章