HTML5引擎Construct2技术剖析(五)
来源:互联网 发布:memcmp linux 编辑:程序博客网 时间:2024/06/04 20:21
当完成初始化工作后,游戏就开始运行了。下面几节来介绍游戏的运行过程。游戏运行过程主要分为几个部分:
(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技术剖析(五)
- HTML5引擎Construct2技术剖析(一)
- HTML5引擎Construct2技术剖析(二)
- HTML5引擎Construct2技术剖析(三)
- HTML5引擎Construct2技术剖析(四)
- HTML5引擎Construct2技术剖析(六)
- HTML5引擎Construct2技术剖析(七)
- 游戏引擎剖析(五)
- 游戏引擎剖析(五)
- 游戏引擎剖析(五)
- 游戏引擎剖析(五)
- 游戏引擎剖析(五)
- 【转帖】游戏引擎剖析(五)
- construct2游戏引擎介绍
- 基于引擎开发HTML5游戏实战(五)---游戏部署
- 使用Construct2制作HTML5游戏
- 如何使用construct2制作 HTML5
- 剖析 .Net 下的数据访问层技术(五)
- 开源php中文分词系统SCWS安装和使用实例_php实例
- 视觉中国的NoSQL之路:从MySQL到MongoDB
- Java使用memcached
- python的unittest测试框架的扩展浅谈
- mongodb适合做游戏开发吗?修改
- HTML5引擎Construct2技术剖析(五)
- 如何使用cocos2dx-jsbinding 来处理分辨率适配
- PAT (Advanced Level) 1027. Colors in Mars (20) 进制转换
- tomcat之数据库连接池proxool详细配置
- IOS开发-Prefix.pch文件的用法详解
- fseek,ftell
- 获取某一点的经纬度(高德地图)
- 在linux下使用PPPOE程序拨号连接小区宽带xDSL的方法
- 工作这么多年了,却一直没有什么积累