019年5月28日,白鹭引擎发布 5.2.20版本,在5.2.20版本中,2D渲染 – JavaScript和微信小游戏新增支持KTX纹理存储格式(KTX纹理说明见下文);同时,Egret Native更新至0.1.17版本,新增、修复,优化多项功能,推荐各位开发者更新体验。
KTX 纹理压缩使用说明
一、关于 KTX
KTX (Khronos Texture) 是一种纹理存储格式,大部分移动设备的 GPU 均支持这种格式。可以有效降低设备的显存占用,提高运行效率和稳定性。
如上图所示,第一步我们先把普通的 png\jpg 图片,转换成 ios 系统支持的 PVRTC 和安卓系统支持的 ETC1 格式的纹理。第二步再把纹理打包为 KTX 格式。
二、如何使用 KTX
http://tool.egret-labs.org/DocZip/engine/KTXHello.zip(KTX使用示例,复制链接到地址栏可下载)
上面是一个 HelloWorld 的示例项目,其中只把 egret_icon.png 这个图片转换为KTX 格式使用。
1、资源说明
在 resource/assets 目录下,egret_icon 有如下几种格式,引擎会根据不同平台来读取不同的格式:
egret_icon.png:PC 平台使用;
egret_icon.pvr.ktx:pvr 格式的 ktx,iOS 平台使用;
egret_icon.ktx(etc1 格式的颜色纹理) 和 egret_icon_alpha.ktx(alpha遮罩纹理):安卓平台使用。注:也可以把 2 个 ktx 文件合成一个文件,具体方法请参考高级教程。
2、代码说明
在 Main.ts 中的 loadResource 方法里,我们加了几行代码。
(1)、ignoreResource 方法表示只有 egret_icon.png 这个图片才会进入 ktx的使用流程,其他资源全部忽略;
(2)、CompressTextureProcessor 是加载资源的处理器,我们把它注册到了AssetsManager 资源管理器中。具体的处理逻辑,请看示例中的代码。
3、显示效果
为了更容易看出效果,我们把 egret_icon.png 换成了另外一张白鹭小鸟,而 ktx格式还是标准 HelloWorld 里的白鹭图标。
从上图中很容易看出,左侧是 PC 浏览器中的显示效果,因为不支持 ktx 格式,显示的是 png 图片。而右侧的 iOS 手机浏览器,因为支持 ktx 格式,显示的是pvr 纹理格式的图片。
Egret Native 0.1.17
[新增] 原生渲染支持自定义字体;
[新增] 支持更多的WebGLExtension: OES_texture_float、OES_standard_derivatives;
[优化] Android:带描边的加粗字体加粗不明显;
[优化] Android:按照Google Play白名单调整Android SDK接口调用方法;
[修正] 在打开原生显示列表时,位图字体时可能导致程序崩溃;
[修正] 加载完成的audio在cloneNode之后立即播放无效;
[修正] Android:屏幕弹出键盘时会自动弹回;
[修正] Android:不打开FPS面板时退出异常;
[修正] Android:和不支持ping pong的websocket服务器连接时会断线;
[修正] Android:华为Android8.1系统刘海屏高度支持;
[修正] iOS:单行输入框输入文字超过最大长度后不能自动左移;
[修正] iOS:多行输入框输入文字颜色不正确;
[修正] iOS:放大模式下正确识别屏幕分辨率;
[修正] iOS:post请求数据量过大引起崩溃。
近有空开了一个简单的油价小程序,分享给大家学习。(适合新手练手项目,大神们请多指教)
首先展示一下小程序
<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
小程序分两屏,首屏展示的是每个城市的油价、每日黄历、分享功能、定位当前城市功能;第二屏展示的是每日笑话。
完整效果可以搜索小程序:悟空仔油价
?
开发详情:
1、首先介绍开发工具
(1)、开发小程序常用的有微信官方提供的工具 -- 微信开发者工具。
工具介绍链接:https://developers.weixin.qq.com/miniprogram/dev/devtools/devtools.html
?
(2)、白鹭科技推出的Egret Wing
http://developer.egret.com/cn/github/egret-docs/Wing/ui/index.html
?
小程序目录
?
2、小程序Appid,每个小程序对应一个appid,如果要开发上线的小程序,首先需要注册一个小程序,注册地址:https://mp.weixin.qq.com/wxopen/waregister?action=step1;如果只是练习小程序项目,可以使用测试appid
?
完成之后就可以愉快的开发小程序了
3、安装小程序插件 Vant Weapp
本项目使用了小程序插件 Vant Weapp,项目地址:
https://vant-contrib.gitee.io/vant-weapp/#/quickstart
安装插件的方法有详细说明,步骤四 构建 npm 包的时候如果提示没有找到文件夹,首先先创建文件夹miniprogram
?
4、城市列表获取
全国城市的获取,本来想用vant 提供的数据插件,结果引用失败,没办法,直接新建了js文件,复制到了里面。
小伙伴可以尝试下,能不能引用成功:
https://vant-contrib.gitee.io/vant-weapp/#/area
?
?
5、获取当前登录用户的位置信息(使用微信的位置接口和腾讯地图的小程序SDK)
https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview
第一步、使用微信提供的位置接口:wx.getLocation(Object object)
https://developers.weixin.qq.com/miniprogram/dev/api/location/wx.getLocation.html
?
获取到当前打开用户的经纬度信息
第二步、使用腾讯地图的小程序SDK的reverseGeocoder(options:Object)方法获取城市信息
https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/methodReverseGeocoder
?
6、获取今日油价、今日黄历和笑话接口
采用了聚合数据的免费接口,只需注册,就可以有每天100次的免费接口访问权限
注册地址:https://www.juhe.cn/
?
笑话展示页面使用了scroll-view的组件
https://developers.weixin.qq.com/miniprogram/dev/component/scroll-view.html
请求接口之前封装了_get和_post方法
?
7、本来是想做文章资讯页,但是文章资讯的小程序要有审核资质,所以改成了笑话页;
文章详情页的页面还保留着,需要的小伙伴可参考下
?
开发不易,小程序源码下载链接:
https://mp.weixin.qq.com/s/FrrZbXMVrUV45q_pu8uGQg
或者关注关注公众号:忧郁的悟空仔
?
?
用一个简单的游戏开发示例,由浅入深,介绍了如何用Laya引擎开发微信小游戏。
微信小游戏的推出也快一年时间了,在IEG的游戏运营活动中,也出现了越来越多的以小游戏作为载体运营的活动类型,比如游戏预约,抢先试完等等,都收到了非常良好的效果。
在支持微信小游戏的游戏引擎中,Cocos,Egret,Laya都对小游戏的开发提供了很多强大的支持。前段时间正好抽空研究了一下这块的内容,现做一个总结,针对如何使用Laya引擎开发微信小游戏给大家做一下介绍。因为时间有限,研究并不深入, 如有高手路过,忘不吝赐教。
做个啥游戏呢?“绝地求生”很火,我们做个“绝地求死”如何?策划也很简单,和绝地求生相反,主角不是跳伞的玩家,而是地面的炮手,大炮要把跳伞的伞兵用大炮一个个都消灭掉。
牛逼的策划有了,咱们进入正题,看看怎么实现吧!
1. 如果不用引擎会怎样?
1.1 Canvas了解下
微信小游戏提供了canvas这个游戏核心组件。利用Canvas可以在画布上画出文字、图形、图像等等。 不过讲微信小游戏之前,得先说说H5,在H5时代获取canvas对象非常简单,如下图:
var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d");
常用的一些API:
ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); //绘制图片 ctx.fillText(text,x,y,maxWidth); //绘制文字 ctx.rect(x,y,width,height); //绘制矩形 ctx.clearRect(x,y,width,height);//清除矩形内像素 ctx.scale(scalewidth,scaleheight);//缩放 ctx.rotate(angle);//旋转角度 。。。。
微信小游戏里,也提供了canvas对象,只不过获取接口变了:
wx.createCanvas()
其他H5环境下有的Canvas API,微信环境里也都有。
1.2 动画的原理
Canvas只是一个2D的画布,要做一个游戏,动画总不能少吧?要让图片能动起来,这又是怎么做到的呢?请看下图:
好吧,动画其实就是不断画图片,然后擦除,再画图片,再擦除的循环过程,肉眼看起来,那就是动起来了。
在古老的电影胶片时代,我们看到的电影,就是一张一张连续帧的胶片组成的,最后投射到大屏幕上,变成了我们看到的电影。
1.3 动画性能优化
但是,动画是讲究帧率的,一般如果能达到每秒60帧,那就和电影一样是很流畅的动画效果了。计算公式:1000ms/60fps=16.67ms,这就要求我们每次动画里的业务逻辑计算,都要16.6ms里完成,不能影响下一帧的显示,否则就是卡顿,也就被人说这个游戏好卡,性能好差了。
知道原理了,性能优化具体怎么做呢?
当然还有很多其他更多的技巧和手段来提升canvas的性能,在这样的情况下如果我们直接使用canvas去开发一个游戏,还会面临比如碰撞算法、物理系统之类的问题。 所以,如果只用canvas去开发游戏,就如同你在吃鸡游戏里,只拿了一把平底锅,你怎么和别人正面刚?
所以,我们需要一把98K把自己武装起来,那就是使用游戏引擎开发。
2. 为什么选择Laya?
目前支持微信小游戏的引擎,有Cocos,Egret,Laya,我们先看下三者的功能比较:
从各种支持度上来讲,laya是目前支持度最好的,也据laya侧的宣传,他的性能也是最高的。(关于性能的问题,因外部水军比较多,在没有做实际详细测试前,暂时不发表评价。)
在公司内部,都有三种引擎的游戏实现,下面是截止5月份的公开数据的引擎占比:
其实三个引擎都提供了很好的支持度,一般来说,如果原先使用过Cocos实现过APP端游戏要移植到微信小游戏端来的,使用Cocos是最好的选择,如果是从头开发一款小游戏,那还是在Egret和Laya里选择一款吧!
3. Laya 环境搭建
前面讲了那么多,都还只是前戏,只是为了大家对游戏的开发有个初步的了解,从这一节开始我们就进入正题了。
到 https://www.layabox.com/ 去下载最新的版本,并进行安装。目前有1.X版本和2.0版本。(本文使用1.7.20版本做示例)
然后就可以创建一个新的游戏项目了,我们可以现在选择创建一个UI示例项目
[ 创建新工程 ]
3.1 代码模式
当然就是给你写代码的地方,感觉这个编辑器,就是在VSCode的基础上改的。连最顶上的Code标识都还在。也因为这样,所以才能很好的支持TypeScript。
[ 代码模式布局 ]
为什么要使用TypeScript? 本文不详细展开比较,只需要了解TypeScript 是Javascript的超集,因为多了个“Type”表示他支持强类型,并且由于静态类型化,在写代码的时候编辑器就能提示你的错误,所以更适合开发游戏这种逻辑复杂的应用就好了。当然最终TypeScript还是会像ES6一样,被编译成普通的Javascript执行。但是在开发阶段管理代码来说,已经可以驾驭大型项目了。
3.2 设计模式
就是用来设计UI界面的地方,拖拖拽拽就可以把游戏页面整出来。Laya提供了好多组件,如果有需要的可以使用,当然也可以不用他的组件,自己搞自己的自定义组件。
[ 设计模式布局 ]
4. Laya的HelloWorld
都说作为一个程序员,买来文房四宝之后,写下的第一行字,一定是“Hello World”。(我拿着公司刚发的 20周年LAMY纪念钢笔,写的第一行字,居然也是“Hello World”,汗~~~)
4.1 游戏初始化
4.1.1.GameMain.ts
首先删掉系统刚才默认的文件“LayaUISample.ts”,然后新建文件GameMain.ts
import WebGL=Laya.WebGL; class GameMain { constructor() { //TS或JS版本初始化微信小游戏的适配 Laya.MiniAdpter.init(true,false); //初始化布局大小 Laya.init(375,667, WebGL); //布局方式设定 Laya.stage.scaleMode=Laya.Stage.SCALE_SHOWALL; Laya.stage.screenMode=Laya.Stage.SCREEN_VERTICAL; Laya.stage.alignV=Laya.Stage.ALIGN_CENTER; Laya.stage.alignH=Laya.Stage.ALIGN_CENTER; } } new GameMain();
Laya.MiniAdpter.init()是Laya提供的对小游戏提供的适配,因为在小程序&小游戏环境下,并没有Bom和DomAPI,比如,没有window,document, 所以需要这样一个适配器,对小游戏的开发方式,进行兼容。
4.1.2. bin/index.html
修改bin目录下的index.html ,删掉LayaUISample.ts的引用,改为下面的方式:
<!--启动类添加到这里--> <!--jsfile--Main--> <script src="js/GameMain.js"></script> <!--jsfile--Main-->
在index.html里,提供了很多Laya的类库,这些类库,最终会被打包成合并一个code.js. 因为微信小游戏的体积限制,我们不需要把所有的库都加载进来,只选择我们需要的库就好了,用不到的可以都删除。
4.1.3. run
接下来,点击运行,就会出现模拟器界面了。
[ 运行模拟器 ]
先别管黑乎乎的一团,下面我们就要增加“Hello World”了。
4.2 绘制文字
4.2.1. Laya.Text
再次修改GameMain的代码如下,重点是var txt:Laya.Text=new Laya.Text();
import WebGL=Laya.WebGL; class GameMain { constructor() { //TS或JS版本初始化微信小游戏的适配 Laya.MiniAdpter.init(true,false); //初始化布局大小 Laya.init(375,667, WebGL); //布局方式设定 Laya.stage.scaleMode=Laya.Stage.SCALE_SHOWALL; Laya.stage.screenMode=Laya.Stage.SCREEN_VERTICAL; Laya.stage.alignV=Laya.Stage.ALIGN_CENTER; Laya.stage.alignH=Laya.Stage.ALIGN_CENTER; //创建Text对象 var txt:Laya.Text=new Laya.Text(); //给Text的属性赋值 txt.text="Hello World";//设定文字内容 txt.color="#ffffff"; //设定颜色 txt.fontSize=20; //设定字体大小 txt.pos(100,200); //设定位置 //将Text对象添加到舞台 Laya.stage.addChild(txt); } } new GameMain();
在上面的代码中,我们给Stage舞台上,添加了Text对象,然后点击运行
啊哦,传说中的HelloWorld终于出现了
4.3 绘制图片
4.3.1 loadImage
Laya的Sprite提供了一个非常简单的loadImage方法,可以即时加载图片并加载到舞台上。
//设置舞台背景色 Laya.stage.bgColor="#1e83e8"; //创建img Sprite精灵 var img:Laya.Sprite=new Laya.Sprite(); //加载显示图片,坐标位于100,50,并设置宽高 130*108 img.loadImage("demo/paratrooper.jpg",100,50,130,108); //把图片添加到舞台 Laya.stage.addChild(img);
预览如下,是不是很简单?
但是这个方法,其实并不实用,在真实项目中,一般会有很多图片,我们不会一张一张图片的去加载,而是预先加载好,再去显示图片。也就是我们常常在游戏主界面看到的进度条,其实就是在加载资源。
4.3.2 资源预加载
Laya提供一个资源加载器:Laya.loader ,来解决加载的问题。我们把上面的代码再修改下,实现先加载完图片,然后再绘制图片。
private imgPath1:string="demo/paratrooper.jpg"; private imgPath2:string="demo/shell.jpg"; constructor() { //.....省略N行代码 this.renderImage(); //....省略N行代码 } renderImage():void{ //定义图片路径集合 var resArray=[ {url:this.imgPath1,type:Laya.Loader.IMAGE}, {url:this.imgPath2,type:Laya.Loader.IMAGE} ] //使用加载器加载图片路径 Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress)) } //加载完成后,把图片绘制到画布上 onLoadComplete():void{ console.log("加载完成"); var img1:Laya.Sprite=new Laya.Sprite(); img1.graphics.drawTexture(Laya.loader.getRes(this.imgPath1),100,50,100,100); Laya.stage.addChild(img1); var img2:Laya.Sprite=new Laya.Sprite(); img2.graphics.drawTexture(Laya.loader.getRes(this.imgPath2),100,300,100,100); Laya.stage.addChild(img2); } //这里可以获取到加载的进度,以后可以制作进度条 onLoadProgress(percent:number):void{ console.log("percent->"+percent); }
4.3.3 图集
只是预加载图片还不够,实际场景由于有很多小图片,所以我们可以把这些小图片拼合成图集,这就类似在前端在做性能优化的有时候所使用的css sprite精灵图,这样制作成图集,不但加载性能更高,而且也更便于制作帧动画。
图集的加载类似这样:
var resArray=[ {url:"res/atlas/demo.atlas",type:Laya.Loader.ATLAS}, ] Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress))
和之前的图片加载时Laya.Loader.IMAGE不同的是,type变成了Laya.Loader.ATLAS。
那图集怎么制作呢?还有,大量的游戏界面,真的就靠手动一张图片一张图片的显示吗? 当然不!因为我们接下来该了解下UI编辑器了。
5. UI编辑器
UI编辑器,当然是用来编辑UI的,大多数的客户端程序开发环境,都有类似的UI编辑器。点击左侧的
图标,进入UI编辑器模式,如下图:
具体UI编辑器的功能介绍,建议还是看官方文档,这里就不赘述了。
5.1创建UI
因为我们创建的是默认UI项目,所以UI编辑器里,有一个TestPage.ui,可以不用管他,我们创建一个自己的UI。 点击 文件->新建文件
进入新建页面窗口,页面类型有View 和Dialog两种,因为这里我们做的是整个页面,所以选View。如果你有兴趣去看源码,其实Dialog也是基于View实现的,只不过多了Dialog的一些特性。
如果对这个view后面还有逻辑代码要写,建议勾选“创建逻辑类”,这样就会自动在View目录下自动创建一个和UI对应的GamePage.ts
[ 新建页面UI ]
5.2 导入资源
在assets目录下,新建一个demo资源目录,把需要的图片都扔进去,然后在UI编辑器的资源面板最下方找找到刷新按钮
,新增资源图片后,一定要记得点下刷新,否则资源面板的内容不会自动刷新。
只要是demo文件下的图片,都会被自动打包成图集,路径就是 res/atlas/demo.atlas。 不知道有没有同学发现,在上面的图片中,有部分资源显示“不打包”,这是什么原因的?
点击文件-》项目设置,我们会看到图集限制了能被打入图集的单图的最大宽高,和最终图集的最大宽高,默认标准可以自行修改。超过这个图集标准的图片,就不会打包到图集中去,就需要手动加载了。
[ 请在这里填写图片描述 ]
5.3 编辑UI
编辑页面功能,会用ppt的,应该都会用了,拖个图片谁不会?直接把资源管理器的图片,拖到右侧场景编辑器里。这次我们拖了一个蓝天白云的背景,并在最下方放了一个大炮,看起来还有点意思。
顶部有一排图标,是用来协助对齐图片用的,提供了顶部对齐,底部对齐,左对齐,右对齐,中线对齐等等,如果图片很多,用这个对齐就很方便了。
右侧的属性栏,就比较常用了。 var这里,你可以给你拖进来的图片组件,给个变量名,这个变量名,最后会在之前自动生成的逻辑类里用到。我们把大炮定个变量名“pao”,后面会用到;x,y,width,height这里,就是坐标和宽高,就不用多说了吧?
5.4 导出UI
UI做好以后,有个重要的工作,就是千万别忘记导出。很多初学者,经常会忘记这点。导出UI,才会重新生成图集和UI相关设置。
导出以后,我们看laya/pages/GamePage.ui 文件,不用管里面的详细内容,里面就是刚才我们拖拽图片,自动生成的响应配置文件。
5.5 使用UI
下面我们要把刚才编辑的GamePage显示出来,那就回过头来,再次修改GameMain.ts
class GameMain { //定义静态变量 gamePageView public static gamePageView:view.GamePage; constructor() { //... this.renderImage(); //... } renderImage():void{ //资源加载 var resArray=[ {url:"res/atlas/demo.atlas",type:Laya.Loader.ATLAS}, ] Laya.loader.load(resArray,Laya.Handler.create(this,this.onLoadComplete),Laya.Handler.create(this,this.onLoadProgress)) } onLoadComplete():void{ //初始化view GameMain.gamePageView=new view.GamePage(); //添加到舞台 Laya.stage.addChild(GameMain.gamePageView); } } new GameMain();
运行一下,主界面游戏背景,和大炮都已经架设好了,好的开端,就是成功的一半了。
接下来,根据最初的牛逼策划,我们要像pubgm一样,让伞兵从天下掉下来,怎么实现?接着看动画部分吧!
*请认真填写需求信息,我们会在24小时内与您取得联系。