工程的入口文件一般为Main.ts,这里面不仅需要处理项目相关的逻辑初始化,也会调用Laya3D.init()进行Laya引擎的初始化。
在init中,可以看到创建了两个画布,mainCanvas是引擎的主画布,所有游戏内的canvas和webgl渲染都用这个画布。canvas是一个全局离线画布,不会加到DOM上,主要用来测量字体、获取image数据。
这里也可以直接查看Chrome的结构
接下来创建一系列timer
然后创建一个LoaderManager 赋值给Laya.loader
loaderManager负责加载,加载完后的资源放到_ResMap / @资源map,url做key,resinfo
loaderManager默认支持五个线程 ,可修改 maxLoader
接下来就是创建舞台
最后是创建渲染器
下面看一下render的构造函数都发生了什么
/**
* 初始化引擎。
* @param width 游戏窗口宽度。
* @param height 游戏窗口高度。
*/
constructor(width: number, height: number, mainCanv: HTMLCanvas) {
Render._mainCanvas = mainCanv;
let source:HTMLCanvasElement = Render._mainCanvas.source as HTMLCanvasElement;
//创建主画布。改到Browser中了,因为为了runtime,主画布必须是第一个
source.id = "layaCanvas";
source.width = width;
source.height = height;
if (Render.isConchApp) {
document.body.appendChild(source);
}
this.initRender(Render._mainCanvas, width, height); // 初始化wegGL环境
window.requestAnimationFrame(loop);
function loop(stamp: number): void {
ILaya.stage._loop();
window.requestAnimationFrame(loop);
}
ILaya.stage.on("visibilitychange", this, this._onVisibilitychange);
}
这里发现游戏渲染的主循环是通过 window.requestAnimationFrame不断loop实现的,是程序的主要更新源头
注意 这里的window.requestAnimationFrame并不是原生的浏览器重绘接口函数,已经在前面的 brower._init_方法被覆盖了
//兼容requestAnimationFrame
win.requestAnimationFrame = win.requestAnimationFrame || win.webkitRequestAnimationFrame || win.mozRequestAnimationFrame || win.oRequestAnimationFrame || win.msRequestAnimationFrame || function (fun: any): any {
return win.setTimeout(fun, 1000 / 60);
}
initRender()为话不初始化函数,创建和保存了WebGL上下文环境。如需更改canvas的参数,如设置是否抗锯齿,请在初始化引擎之前设置。(修改config)
Stage中的_loop()函数就是帧循环函数,函数内部调用render函数用于渲染当前context渲染上下文和更新逻辑。
这里主要的功能是:清空画布-----提交渲染----更新逻辑,计时器都是在渲染后更新的
Laya的帧率只有两种,高帧率模式固定60帧,低帧率模式
为双帧处理一次渲染,固定30帧。
stage的父物体是Sprite,Sprite是基本的显示图形的显示列表节点。默认没有宽高,默认不接受鼠标事件,通过graphics可以绘制图片或者矢量图,支持旋转,缩放,位移等操作。同时也是容器类,可用来添加多个子节点。LayaAir引擎API设计精简巧妙。核心显示类只有一个Sprite,Sprite针对不同的情况做了渲染优化,所以保证一个类实现丰富功能的同时,又达到高性能
/**
* 更新、呈现显示对象。由系统调用。
* @param context 渲染的上下文引用。
* @param x X轴坐标。
* @param y Y轴坐标。
*/
render(ctx: Context, x: number, y: number): void {
RenderSprite.renders[this._renderType]._fun(this, ctx, x + this._x, y + this._y);
this._repaint = 0;
}
Sprite的renders函数对renders数组(RenderSprite数组)中的第this._renderType个RenderSprite精灵进行渲染(调用_fun函数),_fun函数是RenderSprite类的方法,定义了属于不同类型的不同的渲染方式,里面都是通过调用Context类的方法进行绘制的
需要注意的是RenderSprite在Laya.init初始化的时候就已经创建了,默认是预创建了8192*2个精灵渲染器。它的渲染_fun类型会根据传入的Sprite的_renderType决定渲染方式。
Context扩展类主要用来进行绘制。
流程图