HTML5引擎Construct2技术剖析
Posted 伪装狙击手
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTML5引擎Construct2技术剖析相关的知识,希望对你有一定的参考价值。
当完成初始化工作后,游戏就开始运行了。下面几节来介绍游戏的运行过程。游戏运行过程主要分为几个部分:
(1)资源加载
前一节介绍过初始化工作的最后就是调用go函数,go函数的工作就是加载资源,显示加载进度,等待资源加载完成后正式进入游戏界面。如果采用WebGL,则会新创建一个overlay_canvas来显示加载进度。
加载界面分为3种样式:显示加载带Logo图片进度条、显示进度条和显示加载进度百分比文字。
加载界面也支持Layout来实现更为复杂、效果更炫的加载背景。如果加载界面使用Layout,,则go函数中加载的资源仅仅是那个Layout所使用的资源,而游戏的其他资源会在加载Layout界面运行时才开始加载;否则go函数中会加载所有游戏使用的资源。
加载资源主要包括音频和纹理,纹理列表在前面构造基于Sprite插件的对象类型ObjectType时,会调用OnCreate函数。这个函数中会找到当前精灵对象使用的所有纹理文件,通过waitForImageLoad函数将其加入到runtime的wait_for_textures数组中,等待文件的后台自动加载。音频列表则调用getready函数,通过声音插件Audio的setPreloadList函数找出所有预加载的音频文件列表放入runtime的audio_to_preload数组中,等待文件的后台自动加载。
go函数通过SetTimeout不断回调自己,每次调用都会通过areAllTexturesAndSoundsLoaded函数检查音频和纹理资源是否加载完成,如果完成则执行go_loading_finished函数正式进入游戏状态。
setTimeout((function (self) return function () self.go(); ; )(this), (this.isCocoonJs ? 10 : 100));
(2) 进入游戏
游戏资源加载完毕后,正式进入游戏流程,这是由go_loading_finished函数来完成,其主要流程:
1) 关闭加载界面。如果是WebGL,释放overlay canvas资源。
2) 如果设置使用Layout加载界面,则开始准备游戏资源列表(因为前面的资源加载阶段仅加载了Layout加载界面的资源),后台自动加载。
3) 遍历所有界面,创建其中包含的全局对象实例(但不在游戏世界)
for (i = 0, len = this.layouts_by_index.length; i < len; i++)
this.layouts_by_index[i].createGlobalNonWorlds();
if (this.first_layout)
this.layouts[this.first_layout].startRunning();
else
this.layouts_by_index[0].startRunning();
Layout对象的startRunning函数主要流程:
(a) 如果Layout有EventSheet,则调用updateDeepIncludes函数更新其中包含的EventSheet数据。
if (this.sheetname)
this.event_sheet = this.runtime.eventsheets[this.sheetname];
this.event_sheet.updateDeepIncludes();
(b) 遍历在数据解析阶段创建的对象实例,根据对象实例的layer属性,将对象实例放入相应图层的instances数组中。并将每个图层的对象实例按深度进行排序。
for (i = 0, len = this.layers.length; i < len; ++i)
this.layers[i].instances.sort(sort_by_zindex);
(c) 为所有图层创建本图层的初始对象实例,并初始化图层的视口。updateViewport函数仅完成当前图层的旋转设置,获得旋转后的视口坐标。
for (i = 0, len = this.layers.length; i < len; i++)
layer = this.layers[i];
layer.createInitialInstances();
layer.updateViewport(null);
createInitialInstances函数根据initial_instances中的对象实例数据(实例数据才前面解析时仅简单拷贝,没有进一步处理)创建实例对象,
for (i = 0, k = 0, len = this.initial_instances.length; i < len; i++)
initial_inst = this.initial_instances[i];
type = this.runtime.types_by_index[initial_inst[1]];
…
如果对象实例具有Persist(持久化)行为,即实例的状态数据能够跨场景,当切换场景时则该实例不会被删除;如果不具备Persist行为,则会在图层初始时重新创建实例对象。layout.first_visit表示第一次进入该场景。inst.type.global为真,表示该实例为全局对象,不会在退出Layout时被删除回收。如果keep为真,说明该实例不是全局实例,将其加入到initial_instances数组中。
hasPersistBehavior = this.runtime.typeHasPersistBehavior(type);
keep = true;
if (!hasPersistBehavior || this.layout.first_visit)
inst = this.runtime.createInstanceFromInit(initial_inst, this, true);
created_instances.push(inst);
if (inst.type.global)
keep = false;
前面如果调用了runtime.createInstanceFromInit 函数,该函数会将新创建的实例放入runtime.createRow数组中,这里新建的对象实例还没有真正加入实例管理列中。ClearDeathRow函数会将createRow中实例加入到管理列表中,并更新实例的IID。
this.runtime.ClearDeathRow();
(d) 检查所有新创建的对象实例,如果该实例的类型属于某个容器,则创建该容器中的其他类型的实例(即兄弟实例),放到siblings数组中。
for (i = 0; i < created_instances.length; i++)
inst = created_instances[i];
if (!inst.type.is_contained)
continue;
…
for (k = 0, lenk = inst.type.container.length; k < lenk; k++)
…
s = this.runtime.createInstanceFromInit(t.default_instance, inst.layer, true, inst.x, inst.y, true);
this.runtime.ClearDeathRow();
t.updateIIDs();
inst.siblings.push(s);
created_instances.push(s);
(e) 遍历所有新建的实例,为每个实例触发OnCreated事件函数,如果EventSheet中定义了相应的Action,则会触发执行该动作。
for (i = 0, len = created_instances.length; i < len; i++)
inst = created_instances[i];
this.runtime.trigger(Object.getPrototypeOf(inst.type.plugin).cnds.OnCreated, inst);
(f) 触发OnLayoutStart事件函数。
this.runtime.trigger(cr.system_object.prototype.cnds.OnLayoutStart, null);
5) 如果没有使用Layout加载界面,则直接标记加载完成,触发cr.system_object.prototype.cnds.OnLoadFinished事件。由于触发器必须在Layout中执行,因此前面必须先调用Layout的startRunning函数。
this.loadingprogress = 1; this.trigger(cr.system_object.prototype.cnds.OnLoadFinished, null);
6) 遍历所有对象类型,执行onAppBegin函数(如果有的话)。调用tick函数进入游戏循环。
for (i = 0, len = this.types_by_index.length; i < len; i++)
t = this.types_by_index[i];
if (t.onAppBegin)
t.onAppBegin();
this.tick(false);
下一节介绍游戏主循环
以上是关于HTML5引擎Construct2技术剖析的主要内容,如果未能解决你的问题,请参考以下文章