SunShinewyf / issue-blog

技术积累和沉淀

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

egret使用总结

SunShinewyf opened this issue · comments

Egret是一套HTML5游戏开发解决方案,旨在为h5提供更加方便的开发体验。总的来说egret的功能还是很强大的,最近接手的一个需求的时候使用了egret,使用完之后感觉很棒,把自己的一些经验积累下来。

egret的官方文档地址在这里,API很详细。

既然是写使用总结,还是从最简单的安装到使用吧,虽然官方文档里面也写得很清楚(捂脸)。

安装

安装地址移步这里

  • 按照自己的机器安装Egret Engine即可
  • 安装完后打开会出现如下界面:

images

此时我的egret引擎有两个版本,如果你想安装新的版本,可以点击上面图片面板中的"安装其他版本",进行下载,然后将解压之后的安装包拖进安装面板即可。

还要说的一点就是建议安装一个开发egret的编辑器egret wing,安装方式如下:

点击上面图片面板中的左侧边栏的“工具”栏,就会出现对应的一些工具:

images

找到相对应的这个工具,并点击下载即可

新建项目

打开安装的egret wing,并且点击如下位置或者直接到“文件->新建项目"中进行建立新的项目:

images

此时会弹出一个项目类型的面板,根据你的需要选择一种项目类型就行。这里我选择的是Egret Eui项目,然后会弹出如下面板:

images

选择你所需要的库并填写相应的项目目录以及项目名称就大功告成了

运行

你可以直接在egret wing中进行构建,也可以直接在命令行中进行运行:

egret startserver 项目名称 --port 端口号 -a

-a表示会实时监听你文件的变化并且构建编译。
回车之后就会自动跳转到浏览器中,打开的就是你项目的初始的样子:

images

这说明项目已经运行成功了。

egret目录结构

egret使用的是typescript实现的,初始项目目录结构如下:

images

其中不同文件夹对应的功能如下:

  • bin-debug -- 编译之后的代码目录
  • libs -- 构建新项目时勾选的扩展库文件
  • resource --资源文件,包括eui库的一些初始组件文件
  • src -- 真正有效的用于用户开发的逻辑文件
  • template -- 模板文件
  • index.html -- 项目的视图文件
  • egretProperties.json -- egret的配置文件
  • tsconfig.json -- typescript配置文件

egret技术细节

项目的运行流程

打开main.js文件(项目的入口文件),项目运行的时候是首先执行的createChildren()函数,该函数主要功能是加载了一些资源,并且监听了配置文件加载的事件,主要是下面这行代码进行起监听作用:

RES.addEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);

当配置文件加载完成之后就会执行下面的onConfigComplete(),在这个函数里面你就可以load一些图片资源了。并进行监听图片资源组是否加载成功:

   RES.addEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
        RES.addEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
        RES.addEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
        RES.loadGroup("preload");

这里面监听了图片的"加载完成、加载中、资源组加载出错、单个资源加载出错“的事件。所以若是项目中有加载资源的进度条的要求,就可以通过onResourceProgress这个函数进行相应的处理

记住,对于已经监听的事件,若是不需要了或者监听完了,要及时取消,否则就会触发很多问题。
例如在onConfigComplete()函数里面就及时地取消了CONFIG_COMPLETE事件。

 RES.removeEventListener(RES.ResourceEvent.CONFIG_COMPLETE, this.onConfigComplete, this);

当图片资源组加载完成之后,就可以获取图片并且渲染到页面中。
移步到onResourceLoadComplete(),代码如下:

    private onResourceLoadComplete(event:RES.ResourceEvent):void {
        if (event.groupName == "preload") {
            this.stage.removeChild(this.loadingView);
            RES.removeEventListener(RES.ResourceEvent.GROUP_COMPLETE, this.onResourceLoadComplete, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_LOAD_ERROR, this.onResourceLoadError, this);
            RES.removeEventListener(RES.ResourceEvent.GROUP_PROGRESS, this.onResourceProgress, this);
            RES.removeEventListener(RES.ResourceEvent.ITEM_LOAD_ERROR, this.onItemLoadError, this);
            this.isResourceLoadEnd = true;
            this.createScene();
        }
    }

如上,首先是先取消了事件的监听(足以可见及时取消事件的监听是有多么重要),然后开始渲染页面。
根据代码逻辑直接跳转到startCreateScene(),在这个函数里面,只是获取了一些资源并且绘制了一些图案,然后add到舞台中。这样整个项目就完成的构建到渲染页面的整个过程。

容器对象

首选我们在渲染页面的函数startCreateScene()thisthis.stage进行打印,如下所示:

images

images

从上图可以看出,this.stage是包含this,至少从视图的层级上来看。7个children分别是执行this.addChild('元素')之后的结果。而且越排在后面的child深度越浅。也是官网中深度管理的这一章讲述的内容,越在后面,层级越高,也就是在z轴方向上处于最上面。当然你也可以按照如下方式自己设计元素的显示层级:

this.addChildAt(元素,层级数);

也可以如下面所以获取层级对象:

this.getChildAt(层级数);

事件

在一个h5页面中,难免少不了对事件的一些处理,比如对按钮的点击事件。
项目示例中已经列举了一个demo,如下:

let button = new eui.Button();
button.label = "Click!";
button.horizontalCenter = 0;
button.verticalCenter = 0;
this.addChild(button);
button.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onButtonClick,   this);

至于点击之后要触发的逻辑可以卸载onButtonClick中。这里是引用了eui.Button这个组件,默然可以进行点击。但是不是所有的点击事件只能建立在按钮这种元素上呢,其实不是。例如对于egret.Bitmap类的元素,也可以监听其点击事件,只需要如下设置:

let BitmapObj:egret.Bitmap;
BitmapObj = this.createBitmapByName("button_png");
BitmapObj.touchEnabled = true;  //关键是这个
BitmapObj.addEventListener(egret.TouchEvent.TOUCH_TAP, this.onButtonClick, this);

对于元素是否含有点击事件,可以到官网的对应api查看。

缩放模式和旋转模式

对于这个部分的内容,我还是觉得直接使用一个文档的地址会比较直观一点。

对于不同的项目,可能需要的显示模式也不一样。
对于强制横屏显示的h5可以直接在html中设置data-orientation="landscape"即可

如何实现视频帧播放

轮播

  • 加载资源
this.loadGroup('preload');
  • 获取资源(必须保证资源已经加载完成)
resourceList: Array<RES.ResourceItem> = RES.getGroupByName(groupName);
    this.resourceTextureList = [];
    for (let item of resourceList) {
        this.resourceTextureList.push(RES.getRes(item.name));         
}

上面代码是获取资源的纹理对象,RES.getRes是针对的已经加载完成的资源,没有加载完成会显示为空。获取成功之后并存放在对应数组中。

  • 监听进入页面的事件
this.stage.addEventListener(egret.Event.ENTER_FRAME, this.repeatPlaying, this);
  • 不断循环
let index = 0;
let bitmap = egret.Bitmap;
this.stage.addChild(bitmap);
index ++;
bitmap.texture = this.resourceTextureList[index];
if(index >= this.resourceTextureList.length){
	index = 0;
}

不断遍历,就会重复播放。

只播一次

对于只播一次的情况,就需要在播放完最后一帧的情况下取消事件的监听即可。

this.stage.removeEventListener(egret.Event.ENTER_FRAME, this.repeatPlaying, this);

如何自定义组件

对于建立了eui项目的文件目录,就会在resource-skins中找到对应的exml文件。如果想自定义一个组件,就需要执行如下步骤:

  • 需要自己新建一个exml文件就行,,然后在egret wing中进行绘画视图。如下图所示:

images

例如对于button控件来说,你可以自定义其他的控件,并且在2中选择需要添加的控件元素,在中间面板进行编辑,然后在 4 区域中进行设置属性(如width,height,x,y等属性),最后在 3 中就会自动生成相应的源码了。

  • src文件夹中建立相应的ts文件,并且使其继承eui.component,代码如下:
class PopBoxPanel extends eui.Component{
   
    public constructor(orientation:string ,instance:egret.DisplayObjectContainer){
        super();

        this.addEventListener(egret.Event.COMPLETE,this.onCreateComplete,this);
        this.skinName = "resource/skins/PopBox.exml";

    }
    
     private onCreateComplete(event: any){
         this.removeEventListener(egret.Event.COMPLETE,this.onCreateComplete,this); 
       
    }

}
  • resource-default.thm.json中按照所给格式添加你定义的组件即可
declare module skins{
	class ButtonSkin extends eui.Skin{
	}
}
  • 直接仿造已有类库那样进行使用就行。

bug记录点

  • 在一些低端android设备中,有些会显示不出来,需要在html中找到这一行:
egret.runEgret({renderMode:"webgl", audioType:0});

webgl改为canvas即可

  • 对于有多个视频帧播放的情况下,会出现播放重叠的情况,这是因为在播放下一个视频帧的时候没有及时取消对上一个视频帧的监听。也就是
this.stage.removeEventListener(egret.Event.ENTER_FRAME, this.repeatPlaying, this);
  • 在资源未加载完成就使用RES.getRES()
    需要在资源加载完成之后的回调里面再使用,否则资源会为空。

  • ios不能自动播放背景音乐
    需要给当前的stage添加一个事件(如点击事件)来设置其开始播放

  • scroller组件滑动默认是可以上下左右滑动,需要设置一个属性值来控制只能在垂直方向进行滑动
    bounces : boolean是否启用回弹,当启用回弹后,ScrollView中内容在到达边界后允许继续拖动,在用户拖动操作结束后,再反弹回边界位置

  • 在ios端播放音频会出现下面的问题,如下图所示:

images

这个egret官方给出的回应是如下:

使用格式工厂。选择 44100Hz,96kbps 转换。

  • 音频在android的uc浏览器播放不出声音,需要将音频改成如下格式:

12000hz双声道mp3,比特率20kps

仍在试坑中,后续bug会补上

总结

egret对于一些h5场景还是很使用的。而且文档详尽,上手比较简单。

牛逼啊