设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2576|回复: 4
打印 上一主题 下一主题

[交流讨论] RPG Maker MV 的源码研究 十三

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1882
在线时间
1552 小时
注册时间
2013-4-13
帖子
917
跳转到指定楼层
1
发表于 2019-8-23 22:53:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
Scene_Map算是比较复杂的场景了
目测水上十篇是没问题的
====================================
我们这次先笼统得了解一下整个场景的功能
然后再慢慢逐个分析其具体实现
先是构造函数和create方法

  1. Scene_Map.prototype.initialize = function () {
  2.   Scene_Base.prototype.initialize.call(this);
  3.   this._waitCount = 0;
  4.   // 打开菜单的缓冲帧
  5.   this._encounterEffectDuration = 0;
  6.   // 遇敌过场持续时间
  7.   this._mapLoaded = false;
  8.   // 地图加载状态标识
  9.   this._touchCount = 0;
  10.   // 触摸计时器
  11.   // 玩家持续按下鼠标可以引导角色前往当前鼠标的位置(>15帧)
  12. };

  13. Scene_Map.prototype.create = function () {
  14.   Scene_Base.prototype.create.call(this);
  15.   this._transfer = $gamePlayer.isTransferring();
  16.   // 过场标识
  17.   // 这个在Scene_Title交接的时候设置为true了
  18.   var mapId = this._transfer ? $gamePlayer.newMapId() : $gameMap.mapId();
  19.   // 如果是过场, 加载新地图, 否则加载当前地图
  20.   DataManager.loadMapData(mapId);
  21. };
复制代码

然后是start方法

  1. Scene_Map.prototype.start = function () {
  2.   Scene_Base.prototype.start.call(this);
  3.   SceneManager.clearStack();
  4.   // 场景管理器清空场景栈
  5.   if (this._transfer) {
  6.     // 如果是过场
  7.     this.fadeInForTransfer();
  8.     // 过场淡入效果
  9.     this._mapNameWindow.open();
  10.     // 地图名字窗口打开
  11.     $gameMap.autoplay();
  12.     // 自动播放地图音乐
  13.   } else if (this.needsFadeIn()) {
  14.     // 如果从战斗或者录取记录场景切换回来则进行淡入
  15.     this.startFadeIn(this.fadeSpeed(), false);
  16.   }
  17.   // 设置呼叫菜单状态为false
  18.   this.menuCalling = false;
  19. };
复制代码

然后是update方法

  1. Scene_Map.prototype.update = function () {
  2.   this.updateDestination();
  3.   // 判断玩家输入, 设置角色移动目的
  4.   this.updateMainMultiply();
  5.   // 更新游戏对象
  6.   if (this.isSceneChangeOk()) {
  7.     // 更新场景
  8.     // 游戏结束/地图切换/遇敌/呼叫菜单
  9.     this.updateScene();
  10.   } else if (SceneManager.isNextScene(Scene_Battle)) {
  11.     // 如果正在进入遇敌场景, 更新遇敌动画效果
  12.     this.updateEncounterEffect();
  13.   }
  14.   // 更新菜单缓冲计数器
  15.   this.updateWaitCount();
  16.   Scene_Base.prototype.update.call(this);
  17. };
复制代码


其实还有一个中止的生命周期方法会被SceneManager调用


  1. SceneManager.goto = function (sceneClass) {
  2.   if (sceneClass) {
  3.     this._nextScene = new sceneClass();
  4.   }
  5.   if (this._scene) {
  6.     this._scene.stop(); // 在这里
  7.   }
  8. };
复制代码


类似于create和start
stop并不会立刻注销scene, 而是要等到当前的场景完成了手头的任务后才会注销
会触发terminate方法

  1. SceneManager.changeScene = function () {
  2.   if (this.isSceneChanging() && !this.isCurrentSceneBusy()) {
  3.     if (this._scene) {
  4.       this._scene.terminate(); // 在这里
  5.       this._scene.detachReservation();
  6.       this._previousClass = this._scene.constructor;
  7.     }
  8.     this._scene = this._nextScene;
  9.     if (this._scene) {
  10.       this._scene.attachReservation();
  11.       this._scene.create();
  12.       this._nextScene = null;
  13.       this._sceneStarted = false;
  14.       this.onSceneCreate();
  15.     }
  16.     if (this._exiting) {
  17.       this.terminate();
  18.     }
  19.   }
  20. };
复制代码

在Scene_Map里是这个样子的

  1. Scene_Map.prototype.stop = function () {
  2.   Scene_Base.prototype.stop.call(this);
  3.   // 角色立正
  4.   // 嗯 没太搞懂为什么要这么做...
  5.   $gamePlayer.straighten();
  6.   // 关闭地图名称窗口
  7.   this._mapNameWindow.close();
  8.   if (this.needsSlowFadeOut()) {
  9.     // 缓慢淡出
  10.     this.startFadeOut(this.slowFadeSpeed(), false);
  11.   } else if (SceneManager.isNextScene(Scene_Map)) {
  12.     // 过场淡出
  13.     this.fadeOutForTransfer();
  14.   } else if (SceneManager.isNextScene(Scene_Battle)) {
  15.     // 触发战斗
  16.     this.launchBattle();
  17.   }
  18. };

  19. // 父类方法
  20. Scene_Base.prototype.stop = function () {
  21.   this._active = false;
  22. };

  23. Scene_Map.prototype.terminate = function () {
  24.   Scene_Base.prototype.terminate.call(this);
  25.   // 如果不是战斗和地图传送则不清空缓存
  26.   // 并且创建一个截图作为新场景的背景
  27.   if (!SceneManager.isNextScene(Scene_Battle)) {
  28.     this._spriteset.update();
  29.     this._mapNameWindow.hide();
  30.     SceneManager.snapForBackground();
  31.   } else {
  32.     ImageManager.clearRequest();
  33.   }

  34.   if (SceneManager.isNextScene(Scene_Map)) {
  35.     ImageManager.clearRequest();
  36.   }
  37.   // 清理放大/缩小效果
  38.   $gameScreen.clearZoom();
  39.   // 清理可显示对象
  40.   this.removeChild(this._fadeSprite);
  41.   this.removeChild(this._mapNameWindow);
  42.   this.removeChild(this._windowLayer);
  43.   this.removeChild(this._spriteset);
  44. };
复制代码


====================================
这次作为一个新场景的开篇就到这里为止吧,
虽然有点少但是一篇保证一个主题吧
越来越短了 (得意

评分

参与人数 4+4 收起 理由
walf_man + 1 塞糖
wr282828 + 1 精品文章
玄羽 + 1 塞糖
康姆图帕帕 + 1 塞糖

查看全部评分

夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里

Lv4.逐梦者

梦石
0
星屑
6708
在线时间
1266 小时
注册时间
2015-2-7
帖子
128
2
发表于 2019-8-25 15:49:49 | 只看该作者
大佬觉得MV游戏时长久了后,内存占比过大导致闪退的死机的,大可有思路解决啊?
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1854
在线时间
395 小时
注册时间
2014-7-7
帖子
264

开拓者

3
发表于 2019-8-25 20:55:54 | 只看该作者
不喜欢js,动辄就xxx.xxxx.xxxx.xxxxx.xxxx.xxx.xx.xxx.xx.xxx.xx.x.x.x.x.x.x.x.x.xx.x.xx.x.x.xx.xx..x..x..x.x.x...x.x.x
继承也麻烦的要si
也可能只是我不习惯而已吧哈哈

点评

这个是RM源码的年代比较久远的问题https://rpg.blue/forum.php?mod=viewthread&tid=478466可以看下我写的关于js怎么继承, 现在有class的写法方便多了  发表于 2019-8-25 22:00
take is cheap
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
181
在线时间
25 小时
注册时间
2024-1-25
帖子
5
4
发表于 2024-4-5 16:45:00 | 只看该作者
大佬写的好啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-3 01:07

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表