RPGMAKER游戏引擎基于JavaScript的插件制作(七)——可交互对象(1):键盘指令

这篇博客介绍一下几个常见的方法与精灵进行交互,这些方法同样可以用于场景交互,窗口交互,学完之后可以很容易地举一反三。

无论什么交互过程,都可以大致分为四个部分,我将其分为信号约定(什么指令可以发生交互),信号监测(判断是否有信号输入,哪个信号输入),信号输入,事件响应(交互后运行什么方法)几个部分。比如调用插件用的插件指令,信号约定和信号监测就是声明插件指令,信号,信号输入放在事件编辑器里,事件响应放在其它函数或者直接和信号约定放在一起。

常见的交互方法有使用插件指令,键盘指令,鼠标指令等,插件指令大家应该入门的时候已经了解了,这里介绍后面两种。

文章除了教会读者代码怎么写,意思是什么,还分享我自己的学习经历,以供参考。


这次我们要实现的目标是在场景地图显示一个简单的精灵对象,通过点击键盘上的“N”可以让其反复出现消失,如图:
在这里插入图片描述

7.1 建立命名空间,准备相关变量

/*=======================================
controller.js
===================================*/
/*:
*
* @plugindesc 控制精灵演示插件
* @
* @author 进入盛夏之门
*
* @param keyVal
* @desc 快捷键键值(键盘N键是:78)
* @default 78
*
*/

//常规工作——设置命名空间
//当需要管理多个命名空间时,使用作者名缩写+子空间名更加规范
var JRSXZM = JRSXZM || {};  
JRSXZM.controller = {};
JRSXZM.controller.parameters = PluginManager.parameters('controller');
//这是个用于判断当前是否需要精灵的变量,更规范的写法是用一个函数储存
JRSXZM.controller.isShowSprite = 1;

当我们自己编辑插件变多时,使用更规范的“作者名缩写+子空间名”更有利于管理。
在设定命名空间的位置准备一些判断状态的函数或者变量,一般情况下,这些内容放在函数里,这里由于判断比较简单就直接用一个变量。

7.2 定义一个简单的精灵

用上一章的方法,我们可以很轻松地定义一个简单地精灵类,注意,我下面的代码使用的类名与上次相同,大家写的时候不能在不同插件里重复定义两个同名类。


//用复制式重写定义一个简单的精灵
//我们对系统提供的精灵类进行复制,创建一个"mySprites"
function mySprites() {
    this.initialize.apply(this, arguments);
}
mySprites.prototype = Object.create(Sprite.prototype);
mySprites.prototype.constructor = mySprites;
mySprites.prototype.initialize = function () {
    Sprite.prototype.initialize.call(this);
    this.setFrame(-30, -30, 200, 200);
    this.createAll();  // 默认一开始就创建精灵
   
};

mySprites.prototype.createAll = function () {
    this._clock = new Sprite(ImageManager.loadBitmap('img/pictures/', "clock", true));
    this._clock.anchor.x = this._clock.anchor.y = 0.5;
    this._clock.setFrame(-30, -30, 200, 200);
    this.addChild(this._clock); //将子精灵_clock加入到容器mySprites中
};

7.3 消息约定

键盘的消息是怎么传入计算机的呢?我们知道,键盘每个键位都对应一个键值,可以找到RM源码 “rpg_core.js"中,一些键值和字符串绑定,我们可以猜到字符串就是约定的“指令”
在这里插入图片描述
这种格式大家可能没见过,简单地说就是以函数的形式建立对象,在JSON表中常用,这个对象中的变量可以用数组的形式调用,如:

Input.keyMapper[9]=='tab';

仿照这种格式,我们给键位N绑定一个指令标志:

//消息约定——设立键值
//这里给键值78绑定了一个标志“interact"
Input.keyMapper[JRSXZM.controller.parameters['keyVal']] = 'interact';

绑定了N,我们只是赋予其一个系统中的职称,就像”张三是个主任“,但是我们并没有告诉它要做什么,所以我们得知道系统是怎么通过这个标志进行事件响应的,也就是“如果你是主任,你要做什么”

我们自然地想到从刚才地代码里面找,如搜索一下’ok’指令,可以找到:
在这里插入图片描述
从这段代码可以读出几个信息:
1.键盘的响应可以通过 _onKeyDown函数进行;
2.输入的键值储存在对象”event.keyCode"中。
然而注释中写的"private"私有函数无疑泼了我们一桶冷水,实际上,在此之外调用Input._onKeyDown或者event.keyCode都会报错。但是没必要灰心,可能有多个函数都可以获得键值并且进行响应,之所以不同是因为响应的时间或者条件不同。而且我们已经大概知道要在Input对象里面寻找了。

可以直接在帮助文档中找到这个函数"Input.isTriggered(ketName)":
在这里插入图片描述
找到这个函数就是找到下达命令的窗口,有了它,我们就可以对顶着“interact”头衔的N键下令了。

7.4 创建精灵

我们接下来先把精灵创建出来。

如果按照上次的经验,也把精灵初创建部分写在场景刷新函数(Scene_Map.prototype.update)里,是会出问题的,问题就是精灵无论如何都保持着最初的状态,如下代码:

//这是错误的反面教材
JRSXZM.controller.SUBupdate = Scene_Map.prototype.update;
Scene_Map.prototype.update = function () {
    JRSXZM.controller.SUBupdate.call(this);
    this.myMapSprite = new mySprites();
    this.myMapSprite.opacity = 255;
    this.addChild(this.myMapSprite);
    //下面是消息监测和响应部分,略
};

这是因为每一次刷新窗口,系统都重新创建一次精灵,这就意味着重新调用一次精灵初始化函数,无限次死而复生,任凭你怎么处理都那它没办法(注:新创建的同名精灵会覆盖掉之前的精灵)。

所以我们要让精灵之初始化一次,也就是和窗口初始化一起进行:

//精灵的构造正确方案
JRSXZM.controller.SUBcreateAllWindows = Scene_Map.prototype.createAllWindows;
Scene_Map.prototype.createAllWindows = function () {
    JRSXZM.controller.SUBupdate.call(this);
    this.myMapSprite = new mySprites();
    this.myMapSprite.opacity = 255;
    this.addChild(this.myMapSprite);
};

7.5 消息响应,消息监测

先设计一个精灵用来响应的方法。
这个方法是改变精灵自身的属性,所以写在“mySprites”的原型链里,如下:

//消息响应——设置精灵用来响应的方法
mySprites.prototype.changeMySprite = function () {  
    if (JRSXZM.controller.isShowSprite == 1) {
        this.opacity = 0;
        JRSXZM.controller.isShowSprite = 0;
        }
    else {
        this.opacity = 255;
        JRSXZM.controller.isShowSprite = 1;
        }   
}

这时可以看出变量JRSXZM.controller.isShowSprite 的作用是判定下一步是展示精灵还是使其消失。
让精灵消失的方法除了设置透明度外,还可将属性visble改为false,大家还可以发挥聪明才智看看精灵能做出用什么其它花样(如曲线运动)。

接下来设置消息监测。
消息监测必须在每一帧都进行,这样才能及时收到我们的信号,这就意味着要把它写在刷新函数里:

//消息监测每一帧都要进行,所以放在刷新函数
JRSXZM.controller.SUBupdate = Scene_Map.prototype.update;
Scene_Map.prototype.update = function () {
    JRSXZM.controller.SUBupdate.call(this);
    //如果监测到键盘指令为“interact”,则执行响应函数
    if (Input.isTriggered('interact'))
        this.myMapSprite.changeMySprite();
};

如果觉得有用请点个赞,如果有什么意见欢迎在评论区提出

发布了9 篇原创文章 · 获赞 24 · 访问量 2020

猜你喜欢

转载自blog.csdn.net/xmoss/article/details/104857017