Laya实战-打地鼠JS版本的ES6重构

前言

在上一篇文章《从零开始制作微信小游戏-弹一弾》中,我使用了纯原生的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官网

猜你喜欢

转载自juejin.im/post/5b4ad97fe51d4519076955e5