Web前端能够转行作游戏吗?

做者:ManfredHu
连接:http://www.manfredhu.com/2018/03/15/31-laya-game-tips/index.html
声明:版权全部,转载请保留本段信息,谢谢你们 html

LayaBoxLayaBox前端

Web前端最近都在跨界!!如今又伸手到游戏领域了。可是真的那么好跨界吗?请让我一一道来。webpack

Canvas和WebGL的出现其实让Web游戏有了实现的可能,可是让咱们用ctx一个个画,效率仍是低了点,因此须要游戏引擎。它帮助咱们去动态渲染游戏每一帧的元素。web

业界比较著名的几个H5游戏引擎,有Egret(白鹭),Layabox,Three.js,coco2d-js等等,详情能够看知乎的回答
由于咱们团队不是一开始作游戏的,咱们是传统意义上的前端团队,从web发家的,起初作的是电商类的业务——拍拍。因此这里咱们综合几家游戏引擎,选择了Layabox。
有以下有点吧:编程

  1. LayaAir是一个优秀的适用于多端的游戏引擎,配备有丰富的组件,有本身的IDE能够快速构建布局等,不须要写相似CSS的代码
  2. 支持html的页面渲染,就是说你可让游戏引擎跟web页面,混用(这在一些相似文本的页面很是有用)
  3. 支持2D、3D甚至VR方面的开发。性能也足够优秀
  4. 对Web前端广泛的上手难度也较其余引擎框架简单不少
  5. 不须要写重构(CSS)代码

其实咱们团队以前也是作得H5竞猜小游戏,不过是基于DOM的,用CSS3作动画。可是发现CSS3操做复杂动画,有不少缺点:小程序

  1. 复杂动画支持度很是差
  2. 页面元素太多,渲染性能差
  3. 不少复杂的需求作起来很耗时
  4. 玩家手机容易发烫(页面元素多,动画复杂)

所以,咱们通过预研和讨论,果断走出传统Web的开发模式,拥抱传统的游戏开发!!固然这里确定不是一路顺风的,从Web前端转向游戏开发,仍是有很是多的坑点的。服务器

首先须要摆脱HTML和CSS,你不是在作页面,你是在作一个游戏!!游戏的逻辑占据了一个游戏80%的工做量,因此你不少时候是在写JavaScript代码,这不是问题,其次,你须要拥有面向对象编程的思想。这多是不少老前端欠缺的,由于JavaScirpt说究竟是一门面向函数、面向过程的语言。你们知道模块化,可是却仍是习惯写function而不是ES6的class微信

这里由于平台也在转型向ES6靠近,因此大胆采用了ES6+Babel+Webpack的模式,甚至于在作Weex、小程序、Web三端融合。即一份代码,能够在三个平台跑。扯的有点远哈,下面开始正文,咱们不说用法,具体是说一些坑点,和优缺点对比。babel

游戏引擎不适用的地方

游戏引擎这东西在动画一块是真心好用,能够高度还原设计师的动画,但是其没有网页的排版布局,更多的布局应该是经过x、y、更改pivot、anchor属性来实现。
CSS能够很快速的经过代码进行相关布局(flex、float、position等属性),网页那种自上而下的内容排版能够自动适应内容,对文字处理十分便捷。框架

针对各自的优缺点,从实现的便捷性来讲,游戏主场景(动画极多)的状况下,为了提升用户的体验,应该用游戏引擎来写。
而对一些活动浮层、投注记录、游戏规则等有大量图片文本的页面,应该用传统的Web网页来编写,这样才是物尽其用的作法。

在这个背景下,游戏开发的前端须要掌握多好几种技能——简单的游戏开发的技能、重构部分的构建技能(团队大前端的趋势下,去除重构岗位,重构工做由前端接管),能够说工做量翻了一倍。可是在业务侧来考虑,由于减小了相关的中间环节,需求迭代能够更快速的落地。

Laya的IDE使用要注意的地方

LayaIDE提供一个组件库,如list列表,tab按钮切换等等简单的Web组件,能够直接拖拽使用而不用本身用代码再实现一次。
可是IDE自带的不少组件有坑点,如list组件的selectHandler触发并不灵敏,数据源从新绑定后会出现点击没法响应的问题,这个时候要绑定mouseHanlder来代替点击事件等。
IDE的使用对于不熟悉的人来讲上手并不简单,熟练后能够提升效率。具体能够看官网的介绍

sceneColor并不起做用

这个属性是IDE的一个配置属性,在引用的时候并不会起做用。能够理解为是一个IDE的背景色,可让你在用IDE编辑的时候看的更清楚。
sceneColor并不起做用sceneColor并不起做用
若是你须要更换背景色,应该经过绘制一个底部的矩形来实现。

1
this.graphics.drawRect( 0, 0, this.stage.width, this.stage.height, '#404d6f'); //设置背景颜色

 

var和name

var

通常组件view下无论嵌套的层级多深,只要有一个var属性的命名,均可以用this.xxx来获取到这个var属性得带组件的引用,并对其进行逻辑操做。

name

而name在特定的组件内name有本身的命名规则,如list下的box,命名为render,能够自动识别该box为list内部渲染节点,设置list的repeat等值,直接简便的实现某些功能。
再譬如dialog界面,咱们设置btn的name为close、yes、no等值,能够直接实现关闭dialog窗口的功能等等。name在这个组件下面也是惟一的,能够用来区分不一样的组件。

top、right对x,y的影响

若是组件设置了top、right等值,在对其进行x,y变化是无效的。
解决方法:IDE经过这些属性设置好布局要取消掉,会转化为对应的x、y值,此时能够操做

图集图片过大致使图片加载失败

以前按照引擎官方人员的建议设置最大合集图片为2048乘以2048,后面通过咱们的测试发现1024宽高比较适配大部分机型,即图片最大不能超过1024,不然微信手Q会有图片load时间过长致使失败的问题。
这里多是部分合并的大图片下载失败,也多是所有下载失败。而后引擎会单独去下载每一个碎片文件,而服务器是没有这些文件的,致使下载所有返回404。应该尽可能避免这种状况发生。

显示区域与点击区域并不彻底相等

用一句话来讲就是:你看到的并不必定是真实的。如我要完成收起按钮,而后隐藏整个浮层。
可是你明明能够看到,绑定的点击事件却没有触发。
这是由于这个层级的高度或者宽度过小,被遮挡这部分是不会触发的。可是是可见的

分离代码和工程

起初是由于不想在LayaIDE下写代码,因此分红了两部分,后面发现这种形式仍是很是OK的,由于Laya工做人员不是传统前端开发,他们的IDE是相似Atom的Electron作的,因此其实运行起来编码体验并非太好。其次是由于IDE会生成图片(png)和图集(atlas)文件,这些图片类的静态资源,更新频率仍是很是高的。若是你只须要修改代码,或者只要修改图片图集,发布一次就行了,不须要同时发布两种。

这样的分离,代码你能够按照你喜欢的方式来写,好比webpack配置工程,好比文件摆放,该怎么放怎么放。再把Laya生成的东西拷贝进来就行了。

设计稿和工程大小

这里咱们设计稿和IDE的宽度高度是彻底对应的,因此不存在换算的问题。也不须要相似CSS的作REM兼容等等操做。你设定宽度是750,高度会自动拉伸,可是显示的页面层级,须要在初始化的时候拉伸一下,否则仍是IDE里面设定的宽高,固然若是你惧怕上面提到的点不到,也能够设定一个很是大的值。

Object.assign兼容

Object.assign是ECMAScript标准的合并对象属性的方法,相似有jQuery的extend等等。
若是你抛弃了jQuery和Zepto等懒得写extend方法,又拥抱了ES6,那你能够像我这样找polyfill来兼容,这里babel官方有个模块
也能够本身选择作兼容,在入口开始的时候载入兼容文件就好。

抗锯齿问题

这个问题是在WebGL下(Canvas不会),会出现graphics.drawCircle绘制的圆环有锯齿问题。以下图:
锯齿问题锯齿问题
左边为没有设置抗锯齿,右边设置了抗锯齿。

1
2
Laya.Config.isAntialias= true; //开启抗锯齿,会消耗一些性能
Laya.init(Browser.clientWidth, Browser.clientHeight, WebGL);

 

mask遮罩不支持抗锯齿

有无锯齿处理的区别有无锯齿处理的区别
如图,下边是没有优化前的,锯齿严重。上边那个图是优化后的,明显边框清晰了不少。
这里以前的思路是矩形头像和mask遮罩为一个总体在前面,而后内边框和外边框层级在后面,可是这样的话,mask遮罩部分如今laya还不会抗锯齿,因此这里对公共头像组件进行参数扩展,加了zOrder参数。让边框盖在头像上,就能够达到抗锯齿的做用。
最后实现的思路以下图层级所示。
头像层级头像层级

Laya几种优化的写法

用Laya自带的属性获取像素比

1
2
3
//var browserHeight = document.body.scrollHeight * window.devicePixelRatio;
var browserHeight = Laya.Browser.height; //会考虑设备像素比,并且会针对特定机型调整补全
`

这个不用本身算了,Laya.Broswer如今能够获取获得了。简化了运算过程

用.super()方法继承父类

Laya.class定义的时候会在原型定义.super方法,直接用就好。两种用法等价,可是看起来.super更简单把?
可能有一些例子是经过xxx._super.call(this)继承父类的,其实直接xxx.super(this)就行了。_super仍是当作私有属性好了。

相关文章
相关标签/搜索