由于一些原因,我开始捣鼓在rmmz做野生了。有关这些原因,也许以后会写,但现在还没空……

言归正传,由于现在我同mz比较熟,其他的几代rm好久没动了,而且我实在嫌弃mv的辣鸡优化(鬼知道我玩逗比危机闪退了多少次),所以就决定尝试研究一番mz野生。虽说已经有了mz版本的野生,但在纸飞机群组里(我没这个新潮平台的账号),抱着“2000这个老东西都能做,mz怎么不能做”的心情,开始尝试,结果虽然说不是一帆风顺,但也是略有困难。

主要体现在素材规格和引擎底层的不同,不过也能比较暴力地规避这些问题,后文再说,先贴一下两个相关网站

野比大雄的生化危机中文Wiki

中文wiki,包括了2000原版、mv版,以及各种主流版本的资源

のび太のBIOHAZARD 新まとめwiki | のびハザ - atwiki(アットウィキ)

日本wiki(好像需要魔法),收录了大部分仍在流传的版本,但是并不提供下载。不过倒是有一些制作教程可以参考

野生系统相关

のびハザの作り方 - のび太のBIOHAZARD 新まとめwiki | のびハザ - atwiki(アットウィキ)

这里有一些从零开始写野生系统的教程,也提供了一些最低限度的素材(还是直接从mv版拿吧)

虽然太过简略,可能和实际使用的有一点出入,不过照着做一遍就差不多理解工作原理,然后大胆地拿原版系统用了

这里列出的分别是:

  • 导入素材
  • 制作准备
  • 按键检测、举枪准备动作
  • 碰撞判定、攻击处理
  • 伤害处理、敌人

下面两个没写的是增加武器种类和固定方向移动,不过对着工程研究应该也比较好懂

另外这里也有一些其他制作工具,不过基本上一个ps或ase就能替代了……

素材问题

mz和mv的图像、音效素材规格基本上是共通的,直接复制就完事了

mz的素材问题主要在动画系统,不过现在也能兼容mv的经典动画了,所以直接把img/animations这个文件夹复制到mz工程里就行

至于数据库,个人只测试了items.json是共通的,其他的可以自己尝试,记得先备份一份原版的数据库

另外,mv的data/animations.json也能直接复制到mz使用!

好吧,好像也没啥了。。

机制问题

有一些问题在日文教程里说到了,这里提出一些适用于mz的做法

按键映射

原版操作需要用到C键进行装弹等等,mz没有做这些按键映射,需要我们自己加

但教程里直接改核心脚本的做法太过狂野,所以就用插件的形式来添加按键映射,我让ai帮写了一个,贴在下面自己用吧。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//=============================================================================
// CustomKeyMapper.js
//=============================================================================

/*:
* @target MZ
* @plugindesc 必要的按键映射
* @author User
* @help
*
* 追加了如下案件映射
* - 数字键 1-5
* - A, C, S
* - Q (映射pageup)
*
*
* @param enabled
* @text 启用
* @desc 是否启用按键映射
* @type boolean
* @default true
*/

(() => {
const pluginName = 'CustomKeyMapper';

const parameters = PluginManager.parameters(pluginName);
const enabled = parameters['enabled'] === 'true';

if (!enabled) return;

const customKeyMap = {
49: '1', // 1
50: '2', // 2
51: '3', // 3
52: '4', // 4
53: '5', // 5
65: 'A', // A
67: 'C', // C
81: 'pageup', // Q
83: 'S', // S
};

Object.assign(Input.keyMapper, customKeyMap);

})();

踏步频率

虽然不太清楚会对游戏有什么影响,但是mz的踏步频率显然比2000要慢很多,所以日文教程这边提供了一个调整用于调整踏步频率的插件

为方便就直接在这贴了,mvmz都兼容,可以直接用(这插件直接改的核心脚本部分,mvmz没有太大的区别)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//=============================================================================
//
//
//=============================================================================

/*:
* @plugindesc rpg_objectsを変更。
* @author S.K
*
* @help
* キャラクターの足踏み頻度を調整できます。
*
* プラグインコマンドはありません。
*
* @param 足踏み頻度
* @type number
* @min 0
* @max 100
* @decimals 1
* @default 1.5
* @desc キャラクターの足踏み頻度です。(MVのデフォルトで1.5)
*/

var parameters = PluginManager.parameters('のびハザ_足踏み速度設定');
var 足踏み頻度 = Number(parameters['足踏み頻度']);

(function() {

Game_CharacterBase.prototype.updateAnimationCount = function() {
if (this.isMoving() && this.hasWalkAnime()) {
this._animationCount += 足踏み頻度;
} else if (this.hasStepAnime() || !this.isOriginalPattern()) {
this._animationCount++;
}
};


})();


踏步频率改成2.5就行了(话说居然用日语做变量名,太狂野了……)

延迟问题

个人认为这是mvmz版的手感和2000版区别的主要原因,在设置移动路线的时候,如果第一个命令为更改图像,那在执行移动路线命令的最开始就会有一点轻微的卡顿

这导致无法流畅的在移动的过程中举枪射击,会有那么一点轻微的卡顿,也影响近战挥刀的手感

问了下ai,说是核心脚本设定必须在停止的状态下才能执行移动路线的命令,好吧,我也不太懂,反正我让它帮我写了个插件,算是解决了这个问题,可以在移动的过程中流畅举枪射击了。。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//=============================================================================
// SmoothMovementRoute.js
//=============================================================================
/*:
* @target MZ
* @plugindesc v1.00 允许玩家在移动过程中执行移动路线中的非移动命令,消除卡顿
* @author Custom
*
* @help
* 本插件解决了以下问题:
* 当玩家在移动过程中通过移动路线设置更改角色图像时,
* 会出现轻微卡顿,因为移动路线命令只能在停止状态下执行。
*
* 本插件允许玩家在移动过程中立即执行移动路线中的非移动命令
*(如更改图像、更改透明度、播放音效等),而不会中断移动。
*
* 使用方法:
* 直接应用插件即可生效。
*/

(function() {
"use strict";

// 定义不需要移动即可执行的命令代码
const NON_MOVE_COMMANDS = [
Game_Character.ROUTE_WAIT,
Game_Character.ROUTE_TURN_DOWN,
Game_Character.ROUTE_TURN_LEFT,
Game_Character.ROUTE_TURN_RIGHT,
Game_Character.ROUTE_TURN_UP,
Game_Character.ROUTE_TURN_90D_R,
Game_Character.ROUTE_TURN_90D_L,
Game_Character.ROUTE_TURN_180D,
Game_Character.ROUTE_TURN_90D_R_L,
Game_Character.ROUTE_TURN_RANDOM,
Game_Character.ROUTE_TURN_TOWARD,
Game_Character.ROUTE_TURN_AWAY,
Game_Character.ROUTE_SWITCH_ON,
Game_Character.ROUTE_SWITCH_OFF,
Game_Character.ROUTE_CHANGE_SPEED,
Game_Character.ROUTE_CHANGE_FREQ,
Game_Character.ROUTE_WALK_ANIME_ON,
Game_Character.ROUTE_WALK_ANIME_OFF,
Game_Character.ROUTE_STEP_ANIME_ON,
Game_Character.ROUTE_STEP_ANIME_OFF,
Game_Character.ROUTE_DIR_FIX_ON,
Game_Character.ROUTE_DIR_FIX_OFF,
Game_Character.ROUTE_THROUGH_ON,
Game_Character.ROUTE_THROUGH_OFF,
Game_Character.ROUTE_TRANSPARENT_ON,
Game_Character.ROUTE_TRANSPARENT_OFF,
Game_Character.ROUTE_CHANGE_IMAGE,
Game_Character.ROUTE_CHANGE_OPACITY,
Game_Character.ROUTE_CHANGE_BLEND_MODE,
Game_Character.ROUTE_PLAY_SE
];

/**
* 检查命令是否为非移动命令
*/
function isNonMoveCommand(command) {
return command && NON_MOVE_COMMANDS.includes(command.code);
}

/**
* 重写 Game_Player.prototype.update
* 在移动过程中也执行非移动命令
*/
const _Game_Player_update = Game_Player.prototype.update;
Game_Player.prototype.update = function(sceneActive) {
const lastScrolledX = this.scrolledX();
const lastScrolledY = this.scrolledY();
const wasMoving = this.isMoving();
this.updateDashing();
if (sceneActive) {
this.moveByInput();
}
Game_Character.prototype.update.call(this);

// 新增:在移动过程中也执行非移动命令
if (this.isMoving() && this._moveRouteForcing) {
this.updateRoutineMoveWhileMoving();
}

this.updateScroll(lastScrolledX, lastScrolledY);
this.updateVehicle();
if (!this.isMoving()) {
this.updateNonmoving(wasMoving, sceneActive);
}
this._followers.update();
};

/**
* 在移动过程中执行非移动命令
*/
Game_Player.prototype.updateRoutineMoveWhileMoving = function() {
// 递减等待计数器
if (this._waitCount > 0) {
this._waitCount--;
return;
}

const command = this._moveRoute.list[this._moveRouteIndex];
if (command && isNonMoveCommand(command)) {
this.setMovementSuccess(true);
this.processMoveCommand(command);
this.advanceMoveRouteIndex();
}
};

/**
* 重写 canMove 方法
* 允许在执行非移动命令时移动
*/
const _Game_Player_canMove = Game_Player.prototype.canMove;
Game_Player.prototype.canMove = function() {
// 如果有移动路线,检查是否只包含非移动命令
if (this.isMoveRouteForcing()) {
const command = this._moveRoute.list[this._moveRouteIndex];
if (command && isNonMoveCommand(command)) {
// 如果当前命令是非移动命令,允许移动
return true;
}
}
// 其他情况使用原逻辑
return _Game_Player_canMove.call(this);
};

})();

插件相关

目前工程中用到了这些插件

省略上面提到的两个,粗略的介绍一下

  • PluginCommanBase:为下面某个脚本准备的前置,dlc自带
  • AnimationFrameRate:调整动画帧率,不过mz好像没用,也不会报错,我也不太清楚调整帧率是否会对游玩体验产生影响,不确定,先放着
  • TemplateEvent:复制事件插件,用来做敌人的,不解释
  • NRP_EventLightLoad:轻量化事件处理,会停止屏幕外的事件处理,不确定用不用得上,先留着
  • MVStyleWindow:将窗口样式变为MV那样,单纯是好看才用的。。
  • NRP_QuickMovementRoute:可以让设置移动路线的命令快速执行,还原2000的效果,不过它并不解决上面提到的延迟问题,主要用于在更改图像后瞬间改变朝向,从而实现演出效果
  • NRP_HideTouchButton:隐藏界面ui按钮和预留区域
  • 还有调用事件插件,因为我发现后面需要用到2000特有的调用事件功能,但我这还没加上

  • Transition200X:可以让XP的过渡渐变图强势回归,我主要是想还原2000打开菜单的过渡效果

最近看日本人写的教程看多了,好像我自己写也有了一股味。。