赞 | 65 |
VIP | 231 |
好人卡 | 2 |
积分 | 19 |
经验 | 35171 |
最后登录 | 2024-9-15 |
在线时间 | 1554 小时 |
Lv3.寻梦者
- 梦石
- 0
- 星屑
- 1912
- 在线时间
- 1554 小时
- 注册时间
- 2013-4-13
- 帖子
- 917
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
下班回来了~继续更~
居然有人看~开心~
=====================================
第三章 Scene_Boot —— SceneManager说要有光
Scene_Boot是整个世界的开始
这次我们就来研究它在它短暂的一生中为我们留下了什么
我们先退回一步来分析一下所有场景的祖宗类: Scene_Base
不过, Scene_Base虽然是最基础的Scene, 但是它又是继承与core.js里的Stage类
然后Stage类又是继承于pixiJs的Container类, 实质上只是Container的一层改名换姓的封装
鉴于我不想最后去读PixiJS的源码
我们就先了解下Container的文档吧:
A Container represents a collection of display objects.
It is the base class of all display objects that act as a container for other objects (like Sprites).
简单来说Container类提供了一个树状的渲染结构每一个节点存在一个children的数组用来记录子节点同时子节点也有一个引用指向其父容器,
我们渲染一个容器的时候可以遍历它的children
并让每个子节点执行自己的渲染方法.
本质上就是个深度遍历.
根据以下pixi.js源码(好吧, 真香)我们可以推断渲染的顺序
- Container.prototype.renderWebGL = function renderWebGL(renderer) {
- // if the object is not visible or the alpha is 0 then no need to render this element
- if (!this.visible || this.worldAlpha <= 0 || !this.renderable) {
- return;
- }
- // do a quick check to see if this element has a mask or a filter.
- if (this._mask || this._filters) {
- this.renderAdvancedWebGL(renderer);
- } else {
- this._renderWebGL(renderer);
- // simple render children!
- for (var i = 0, j = this.children.length; i < j; ++i) {
- this.children[i].renderWebGL(renderer);
- }
- }
- };
复制代码 嗯, 官方写了注释我就不啰嗦了只要注意先渲染容器, 然后从0号child开始依次渲染child, 后渲染的图像会覆盖先渲染的图
好, 我们回到Scene_Base, 它提供了场景比较重要的几个生命周期钩子
initialize: 构造器
- Scene_Boot.prototype.initialize = function() {
- Scene_Base.prototype.initialize.call(this);
- this._startDate = Date.now();
- };
复制代码 只是记录了开始的时间, 只在判断是否加载字体超时的时候用到了
还有create()和start(), 上一次介绍过create和start的区别了, 让我们直接看代码吧
- Scene_Boot.prototype.create = function() {
- Scene_Base.prototype.create.call(this);
- DataManager.loadDatabase();
- ConfigManager.load();
- this.loadSystemWindowImage();
- };
复制代码
这里又出现了两个新Manager, 按照惯例我们以后再细看(可能下一篇就讲DataManager), 这里先简单说一说
DataManage管理数据库(也就是data文件夹下的json文件)和游戏对象(如果是测试的话还会读取测试事件信息)
loadDataBase方法会把数据加载进内存, 也就是你在控制台里输入$dataXXXX看到的东西
其中有一个需要关注的是在加载了System.json, 也就是$dataSystem的时候会反过来出发Scene_Boot的静态方法loadSystemImages
源码暂且贴一下, 以后会再解释(我懒嘛)
- if (object === $dataSystem) {
- Decrypter.hasEncryptedImages = !!object.hasEncryptedImages;
- Decrypter.hasEncryptedAudio = !!object.hasEncryptedAudio;
- Scene_Boot.loadSystemImages();
- }
复制代码
然后这个是loadSystemImages, 目前你只需要知道reserveSystem是读取并缓存图像就好了
- Scene_Boot.loadSystemImages = function() {
- ImageManager.reserveSystem('IconSet');
- ImageManager.reserveSystem('Balloon');
- ImageManager.reserveSystem('Shadow1');
- ImageManager.reserveSystem('Shadow2');
- ImageManager.reserveSystem('Damage');
- ImageManager.reserveSystem('States');
- ImageManager.reserveSystem('Weapons1');
- ImageManager.reserveSystem('Weapons2');
- ImageManager.reserveSystem('Weapons3');
- ImageManager.reserveSystem('ButtonSet');
- };
复制代码 (稍微提一句: 类似data文件或者其他图片/音乐资源的东西加载的时候都是异步)
其实同样在create方法里, 最后还有一个loadSystemWindowImage, 它的实现如下:- Scene_Boot.prototype.loadSystemWindowImage = function() {
- ImageManager.reserveSystem('Window');
- };
复制代码 不要问我为啥他们把代码写得如此分散...我也不知道啊!!
ConfigManager是个系统设置相关的, 等哪天实在没东西可说了我再研究研究它吧
这个名字让我感觉他没有牌面
还记得之前说create会在一开始执行, 而run需要检查准备完毕以后才能执行
那么我们先看看检查函数isReady
- Scene_Boot.prototype.isReady = function() {
- if (Scene_Base.prototype.isReady.call(this)) {
- return DataManager.isDatabaseLoaded() && this.isGameFontLoaded();
- } else {
- return false;
- }
- };
- Scene_Boot.prototype.isGameFontLoaded = function() {
- if (Graphics.isFontLoaded('GameFont')) {
- return true;
- } else if (!Graphics.canUseCssFontLoading()){
- var elapsed = Date.now() - this._startDate;
- if (elapsed >= 60000) {
- throw new Error('Failed to load GameFont');
- }
- }
- };
复制代码
就是检查DataManager和字体是否加载了,
DataManger内容以后再说, font相关的你们有兴趣可以自己看看, 这些都不重要
一旦isReady成立, 下个周期就会执行start
- Scene_Boot.prototype.start = function() {
- Scene_Base.prototype.start.call(this);
- SoundManager.preloadImportantSounds();
- if (DataManager.isBattleTest()) {
- DataManager.setupBattleTest();
- SceneManager.goto(Scene_Battle);
- } else if (DataManager.isEventTest()) {
- DataManager.setupEventTest();
- SceneManager.goto(Scene_Map);
- } else {
- this.checkPlayerLocation();
- DataManager.setupNewGame();
- SceneManager.goto(Scene_Title);
- Window_TitleCommand.initCommandPosition();
- }
- this.updateDocumentTitle();
- };
- Scene_Boot.prototype.updateDocumentTitle = function() {
- document.title = $dataSystem.gameTitle;
- };
复制代码
嗯, 惊了, 居然真的有人去改网页标题了...
咳咳, 这不是重点, 请无视
其实看得出来, 一旦加载完毕Sence_Boot的使命就结束了
和测试相关我们先不去管, Scene_Battle和Scene_Map等到以后遇到了再说
Scene_Title是第一个真正意义上的玩家接触到的场景
等我们把其他系统层面的Manger(可能除了ConfigManager?)分析完了以后再说
嗯, 没错, 这个系列的特点就是日后再说, 也可能日后不说...
水水更健康嘛~
|
评分
-
查看全部评分
|