Project1

标题: 想请教一下原版的代码,有关调用菜单指令的方法 [打印本页]

作者: 雷德尼一凡    时间: 2019-1-4 09:47
标题: 想请教一下原版的代码,有关调用菜单指令的方法
最近在学习一个增加菜单指令的插件,所以一并学习着原版的有关代码,遇到了一些问题,个人力有不逮不得已才来麻烦一下大佬们。

想问的是,原版是通过什么方法来打开菜单的呢?
用press、key做关键词搜索了一下没有找到有关的监听器,用createmenu等类似的词也搜索不到类似的方法。
主要在manager和scene里找的,不知道是不是找错文件了。

恳请大佬们赐教了,非常感谢!
作者: yang1zhi    时间: 2019-1-4 10:15
SceneManager.push(Scene_Menu)
作者: ekmomo    时间: 2019-1-4 10:41
本帖最后由 ekmomo 于 2019-1-4 10:57 编辑

SceneManager起到每帧刷新输入与场景的作用。
这里不贴了,自行查看游戏开始运行时执行的SceneManager.run通过SceneManager.requestUpdate带起的SceneManager.update里面的SceneManager.updateMain。
另外,如果不明白SceneManager.requestUpdate里的requestAnimationFrame的话,推荐百度一下。


下面是Scene.js
  1. Scene_Map.prototype.updateCallMenu = function() {
  2.     if (this.isMenuEnabled()) {
  3.         if (this.isMenuCalled()) {
  4.             this.menuCalling = true;
  5.         }
  6.         if (this.menuCalling && !$gamePlayer.isMoving()) {
  7.             this.callMenu();
  8.         }
  9.     } else {
  10.         this.menuCalling = false;
  11.     }
  12. };
复制代码

  1. Scene_Map.prototype.isMenuCalled = function() {
  2.     return Input.isTriggered('menu') || TouchInput.isCancelled();
  3. };
复制代码


下面在core.js里

  1. Input.isTriggered = function(keyName) {
  2.     if (this._isEscapeCompatible(keyName) && this.isTriggered('escape')) {
  3.         return true;
  4.     } else {
  5.         return this._latestButton === keyName && this._pressedTime === 0;
  6.     }
  7. };
复制代码

  1. Input.update = function() {
  2.     this._pollGamepads();
  3.     if (this._currentState[this._latestButton]) {
  4.         this._pressedTime++;
  5.     } else {
  6.         this._latestButton = null;
  7.     }
  8.     for (var name in this._currentState) {
  9.         if (this._currentState[name] && !this._previousState[name]) {
  10.             this._latestButton = name;
  11.             this._pressedTime = 0;
  12.             this._date = Date.now();
  13.         }
  14.         this._previousState[name] = this._currentState[name];
  15.     }
  16.     this._updateDirection();
  17. };
复制代码
  1. Input._onKeyDown = function(event) {
  2.     if (this._shouldPreventDefault(event.keyCode)) {
  3.         event.preventDefault();
  4.     }
  5.     if (event.keyCode === 144) {    // Numlock
  6.         this.clear();
  7.     }
  8.     var buttonName = this.keyMapper[event.keyCode];
  9.     if (ResourceHandler.exists() && buttonName === 'ok') {
  10.         ResourceHandler.retry();
  11.     } else if (buttonName) {
  12.         this._currentState[buttonName] = true;
  13.     }
  14. };
复制代码


  1. Input.keyMapper = {
  2.     9: 'tab',       // tab
  3.     13: 'ok',       // enter
  4.     16: 'shift',    // shift
  5.     17: 'control',  // control
  6.     18: 'control',  // alt
  7.     27: 'escape',   // escape
  8.     32: 'ok',       // space
  9.     33: 'pageup',   // pageup
  10.     34: 'pagedown', // pagedown
  11.     37: 'left',     // left arrow
  12.     38: 'up',       // up arrow
  13.     39: 'right',    // right arrow
  14.     40: 'down',     // down arrow
  15.     45: 'escape',   // insert
  16.     81: 'pageup',   // Q
  17.     87: 'pagedown', // W
  18.     88: 'escape',   // X
  19.     90: 'ok',       // Z
  20.     96: 'escape',   // numpad 0
  21.     98: 'down',     // numpad 2
  22.     100: 'left',    // numpad 4
  23.     102: 'right',   // numpad 6
  24.     104: 'up',      // numpad 8
  25.     120: 'debug'    // F9
  26. };
复制代码

  1. Graphics._setupEventHandlers = function() {
  2.     window.addEventListener('resize', this._onWindowResize.bind(this));
  3.     document.addEventListener('keydown', this._onKeyDown.bind(this));
  4.     document.addEventListener('keydown', this._onTouchEnd.bind(this));
  5.     document.addEventListener('mousedown', this._onTouchEnd.bind(this));
  6.     document.addEventListener('touchend', this._onTouchEnd.bind(this));
  7. };
复制代码


用到的事件和方法一共就这么多,最后一步Scene.prototype.callMenu楼上说了
  1. Scene_Map.prototype.callMenu = function() {
  2.     SoundManager.playOk();
  3.     SceneManager.push(Scene_Menu);
  4.     Window_MenuCommand.initCommandPosition();
  5.     $gameTemp.clearDestination();
  6.     this._mapNameWindow.hide();
  7.     this._waitCount = 2;
  8. };
复制代码

作者: 雷德尼一凡    时间: 2019-1-4 10:52
啊!谢谢二位,终于大体了解这部分的运作了!
作者: 游鱼戏虾    时间: 2019-3-18 18:04
本帖最后由 游鱼戏虾 于 2019-3-18 21:45 编辑

对不起是我SB了,有几个语法和格式粘贴的时候出错了。框架和我预计的差不多2333


yang1zhi 发表于 2019-1-4 10:15
SceneManager.push(Scene_Menu)


大佬我想问一下,我写了一个显示角色个人背景剧情的窗口,想要作为插件调用,于是把这个actorjs窗口绑定到新建的scene_actojs(照着Scene_status抄的)的,但是在游戏中使用
SceneManager.push(scene_actojs)会提示scene_actojs没有定义,按F8提示的是
SceneManager.catchException @ rpg_managers.js:1949错误, console.error(e.stack);有点儿没搞懂。。。请问这样的思路是错的吗?是不是不能定义其他的scence?有直接调用窗口的命令吗?
作者: ltxfj    时间: 2019-3-18 21:40
游鱼戏虾 发表于 2019-3-18 18:04
大佬我想问一下,我写了一个显示角色个人背景剧情的窗口,想要作为插件调用,于是把这个actorjs窗口绑定 ...

我也正在做新建窗口的测试,正好也遇到了一些小问题,看看能不能解决你的:

以我的小窗口作为例子,我是新增了一个系统选单,在Scene_Menu下新增了个_systemWindow

首先你需要有新建窗口的过程:

JAVASCRIPT 代码复制
  1. Scene_Menu.prototype.create = function () {
  2.     Scene_MenuBase.prototype.create.call(this);
  3.     this.createGoldWindow();
  4.     this.createCommandWindow();
  5.  
  6.     this.createSystemWindow();
  7.  
  8.     this.createStatusWindow();
  9. };


中间那个createSystemWindow()就是新建窗口的命令。这个函数仿照其他几个createWindow窗口的写法来写:

JAVASCRIPT 代码复制
  1. Scene_Menu.prototype.createSystemWindow = function () {
  2.     this._systemWindow = new Window_SystemMenuCommand(坐标, 坐标);
  3.  
  4.     this._systemWindow.setHandler('save', this.commandSave.bind(this));
  5.     this._systemWindow.setHandler('load', this.commandLoad.bind(this));
  6.     this._systemWindow.setHandler('options', this.commandOptions.bind(this));
  7.     this._systemWindow.setHandler('gameEnd', this.commandGameEnd.bind(this));
  8.     this._systemWindow.setHandler('cancel', this.onSystemCancel.bind(this));
  9.  
  10.     this.addWindow(this._systemWindow);
  11. };



第一行估计就是你不成功的关键,你需要把你的窗口new 一下,这样才能成立。最后addWindow一下,把你的窗口加进当前Scene下。然后各个句柄的函数都要写一下,所有没声明的都要声明。


然后,那个new的Window_SystemMenuCommand的整个类是要自己重写的……

这里实在是太多了就贴几个关键的:


JAVASCRIPT 代码复制
  1. function Window_SystemMenuCommand() {
  2.     this.initialize.apply(this, arguments);
  3. }
  4.  
  5. Window_SystemMenuCommand.prototype = Object.create(Window_Command.prototype);
  6. Window_SystemMenuCommand.prototype.constructor = Window_SystemMenuCommand;
  7.  
  8. Window_SystemMenuCommand.prototype.initialize = function (x, y) {
  9.     Window_Command.prototype.initialize.call(this, x, y);
  10.     this.select(last);
  11.  
  12. ………………后面很多很多很多很多
  13. };


简单来说你这个window可以照着你想模仿的那个窗口的完全代码都搬过来,虽然是完全复制但也得有这么一步,记得把名字改了,然后你需要的几个handler记得重写。

到这里大概明白了吗?你的Scene_actojs估计也是少了这个重写的过程,所以人家不认……

--------------------

当然我本身也是正在学写代码的萌新,这个不一定就是你遇到的那几个错误的问题,不过我这边写完的感觉就是无论是窗口Window,场景Scene,都要自己把类重写一下,要不然会各种问题的。

若有前辈指导发现我这边也有问题(笑)的话,你还是听人家的=w=


作者: 游鱼戏虾    时间: 2019-3-18 21:47
ltxfj 发表于 2019-3-18 21:40
我也正在做新建窗口的测试,正好也遇到了一些小问题,看看能不能解决你的:

以我的小窗口作为例子,我是 ...

嗯,谢谢提醒。虽然我的错误不一样的但是和你提到的精神内核很类似哈哈哈
我复制粘贴的时候有几个大小写和;以及}没有加。。。。所以定义代码是不完善的,难怪一直提示我XX未定义。。。
~~共勉~~




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1