Project1

标题: [教程]RMMV脚本教程(二)(更新最终实现代码) [打印本页]

作者: xjzsq    时间: 2017-5-1 13:32
标题: [教程]RMMV脚本教程(二)(更新最终实现代码)
本帖最后由 xjzsq 于 2018-2-6 22:50 编辑

教程一传送门:[教程]RMMV脚本教程(一)
https://rpg.blue/forum.php?mod=viewthread&tid=394509

(出处: 66RPG)

前言
自从上篇教程发布,到现在已经将近1年了吧,在这一年中,由于繁重的学业以及我的懒惰,一直都没有更新...
这次期中考试前夕,我在逛论坛的时候发现有人关注我的教程,并要求我写第二篇,再加上这次期中考试成绩不是很理想,所以下定决心开始写这篇教程。另外@一下支持我、催更的朋友们:@
sfliad
,@zhouhan,@lucy94920,@claudeoy
注意事项
(照抄教程1)
1.本教程提供给一些已经有一点脚本基础的学习者们(至少你要知道变量啊函数啊什么的),如果你没有达到,那我希望你打开着RMMV的F1文档来看这篇教程(F1链接:http://miaowm5.github.io/RMMV-F1/)和机翻RMMV的原生脚本(https://rpg.blue/thread-385523-1-1.html,最近突然发现汪汪大佬在很久以前就把翻译脚本放到了github上,这里放上链接:https://github.com/wangwangxingao/RMMV/tree/master/%E6%B3%A8%E9%87%8A
2.由于本人第一次写教程,因此排版上会有点(非常)乱,请多多包涵;
3.本教程可能会有一些小(或者致命的)错误,请大家积极反馈,让脚本得到完善,另外在教程内我也会有没有调试出来的地方,就请读者们说一说解决方法啦(众:写不出来还做什么教程!);
4.本教程会将RMVA(RGSS3)的语法和RMMV(JS)语法进行比较,让大家学习得更容易一些;
5.本人可能一次写不完一节的教程,会分到好几次编辑,因此会导致写到一半而发了出来的情况,请大家谅解。
6.鉴于本人的学业繁重,三周放一次假,每次放24.5个小时,再加上本人比较懒,因此更新速度会比fei较chang慢,请谅解。
7.本人追随最新潮流,把IDE换成了VS2017。
课后作业答案
1.(略)
(我精心布置的作业竟然没人做,实在是太令人伤心了...
2.①新方法名 = 旧方法名

  1. function Window_MapStatus() {
  2.     this.initialize.apply(this,arguments)
  3. }
  4. Window_MapStatus.prototype = Object.create(Window_Base.prototype);
  5. Window_MapStatus.prototype.constructor = Window_MapStatus;
  6. Window_MapStatus.prototype.initialize = function (x, y, width, height) {
  7.     Window_Base.prototype.initialize.call(this, x, y, width, height);
  8.     this.refresh();
  9. }
复制代码
③A解析略(谁叫你们不回答的...)

正文
上回说到,我们在地图画面成功地创建了一个窗口,但我们的窗口里面还什么都没有啊,因此我们现在我们的窗口里面显示一些文字。
话说上回我们提到了Window_MapName这个窗口,这个窗口里面就一定有显示文字的方法,因此我们打开这个文件。


在这个文件中,我们发现好像这个窗口和我们定义的不太一样,他比我们上节课讲的多了一个设置创造者,因此照抄不误。
另外,我们在refresh方法里面找到了drawText方法,看起来像是显示文字的方法:


但是我们的窗口没有refresh方法呢。我们一直是把方法定义到Scene_Map.prototype.createStatusWindow里面,这是我1年前的想法,但是这样做并不好,因此我们把脚本改成官方的写法:
找到引用refresh的地方:


原来是initialize,因此把我们的initialize改成这样:
  1. Window_MapStatus.prototype.initialize = function (x, y, width, height) {
  2.     Window_Base.prototype.initialize.call(this, x, y, width, height);
  3.     this.refresh();
  4. }
复制代码
(仅仅加了一条refresh)
然后在创造一个refresh方法:
  1. Window_MapStatus.prototype.refresh = function () {

  2. }
复制代码
既然是想显示文字,我们就要看下Window_MapName里面怎么定义的了:


划横线出应该就是了吧。
因此在我们的refresh方法里面也添加上这一句:
  1. this.drawText($gameParty.members()[0]._name, 0, 0, this.Width);
复制代码
这里drawText方法的介绍如下:
drawText ( text , x , y , maxWidth , [lineHeight] , [align] )

在位图上绘制描边文字。

参数:(摘自帮助文档bitmap类,有改动)
在我们的脚本里面,$gameParty.members()[0]._name就是要绘制的文字,两个0是x,y坐标,然后this.Width是获取位图的宽度,文字的行高和对齐方式省略不写。
这个方法就相当于VA中的draw_text方法。
现在运行一下,看看效果:


成功了的说!!!
但是眼尖的同学已经发现默认脚本Window_Base里面已经有一个drawActorName方法了,看一下他的定义:


这里面包含了drawText方法,并且还增加了当角色HP较低时将名字变色的效果,因此比我们的脚本写得更加美观。
因此把我们的
  1. this.drawText($gameParty.members()[0]._name, 0, 0, this.Width);
复制代码
改成
  1. this.drawActorName($gameParty.members()[0], 0, 0);
复制代码
即可。
这里我们的参数也省略了不少,另外在其方法内部可以看到width默认是168,这个值在绘制LV时会用到。
写到这里,先发表出来,以防万一。






作者: xjzsq    时间: 2017-5-1 13:33
本帖最后由 xjzsq 于 2019-6-27 12:20 编辑

糊了好几个晚上代码,今天终于糊完了,发出来。
最终实现代码:
  1. /*:
  2. @author xjzsq
  3. @plugindesc 地图显示角色状态信息
  4. @help


  5. */
  6. var $refresh = true;
  7. function Window_MapStatus() {
  8.     this.initialize.apply(this,arguments)
  9. }
  10. Window_MapStatus.prototype = Object.create(Window_Base.prototype);
  11. Window_MapStatus.prototype.constructor = Window_MapStatus;
  12. Window_MapStatus.prototype.initialize = function (x, y, width, height) {
  13.     Window_Base.prototype.initialize.call(this, x, y, width, height);
  14.     this.opacity = 0;
  15.     this.refresh();
  16. }
  17. Game_Actor.prototype.xjzsq_refresh = Game_Actor.prototype.refresh;
  18. Game_Actor.prototype.refresh = function () {
  19.     this.xjzsq_refresh;
  20.     $refresh = true;
  21. }
  22. Window_MapStatus.prototype.drawGauge = function (x, y, width, rate, color1, color2) {
  23.     var fillW = Math.floor(width * rate);
  24.     var gaugeY = y + this.lineHeight() - 8;
  25.     this.contents.fillRect(x, gaugeY, width, 6, this.gaugeBackColor());
  26.     this.contents.gradientFillRect(x, y + 24, fillW, 6, color1, color2, true);
  27.     this.contents.gradientFillRect(x, y + 30, fillW, 6, color2, color1, true);
  28.     this.contents.fillRect(x, y + 24, width, 2, this.normalColor());
  29.     this.contents.fillRect(x, y + 34, width, 2, this.normalColor());
  30.     this.contents.fillRect(x, y + 26, 2, 8, this.normalColor());
  31.     this.contents.fillRect(x + width - 2, y + 26, 2, 8, this.normalColor());
  32. };
  33. Window_MapStatus.prototype.refresh = function () {
  34.     this.contents.clear();
  35.     this.drawActorFace($gameParty.members()[0], 0, 0);
  36.     this.drawActorName($gameParty.members()[0], 0, 0);
  37.     this.drawActorLevel($gameParty.members()[0], 151, 0);
  38.     this.drawActorIcons($gameParty.members()[0], 0, 108);
  39.     this.drawActorHp($gameParty.members()[0], 151, 36);
  40.     this.drawActorMp($gameParty.members()[0], 151, 72);
  41.     this.drawActorTp($gameParty.members()[0], 151, 108, 186);
  42.     this.drawActorExp($gameParty.members()[0], 0, 144, 346);
  43. }
  44. Window_MapStatus.prototype.update = function () {
  45.     Window_Base.prototype.update.call(this);
  46.     if($refresh){
  47.         this.refresh();
  48.         $refresh = false;
  49.     }
  50.     if ($gamePlayer.screenX() >= 0 && $gamePlayer.screenX() <= this.width && $gamePlayer.screenY() >= 0 && $gamePlayer.screenY() <= this.height)
  51.     {
  52.         this.contentsOpacity = 75;
  53.     }
  54.     else this.contentsOpacity = 225;
  55. }
  56. Game_BattlerBase.prototype.expRate = function () {
  57.     return this.currentExp() / this.nextLevelExp();
  58. };
  59. Window_MapStatus.prototype.drawActorExp = function (actor, x, y, width) {
  60.     width = width || 186;
  61.     var color1 = this.tpGaugeColor1();
  62.     var color2 = this.tpGaugeColor2();
  63.     this.drawGauge(x, y, width, actor.expRate(), color1, color2);
  64.     this.changeTextColor(this.systemColor());
  65.     this.drawText(TextManager.expA, x, y, 44);
  66.     this.drawCurrentAndMax(actor.currentExp(), actor.nextLevelExp(), x, y, width,
  67.                            this.tpColor(actor), this.normalColor());
  68. };

  69. Scene_Map.prototype.createDisplayObjects = function () {
  70.     //创建精灵组
  71.     this.createSpriteset();
  72.     //创建地图名称窗口
  73.     this.createMapNameWindow();
  74.     //创建窗口层
  75.     this.createWindowLayer();
  76.     //创建所有窗口
  77.     this.createAllWindows();

  78.     //创建一个显示角色状态的窗口
  79.     this.createStatusWindow();



  80. };
  81. //创建
  82. Scene_Map.prototype.xjzsq_create = Scene_Map.prototype.create
  83. Scene_Map.prototype.create = function () {
  84.     this.xjzsq_create()
  85.     var face = ImageManager.loadFace($gameParty.members()[0]._faceName);
  86.     var icons = ImageManager.loadSystem('IconSet');
  87. };

  88. //创建一个显示名字的窗口
  89. Scene_Map.prototype.createStatusWindow = function () {
  90.     this._StatusWindow = new Window_MapStatus(0, 0, 410, 216);
  91.     this.addWindow(this._StatusWindow); //窗口添加到窗口层
  92. };
复制代码




作者: xjzsq    时间: 2017-6-12 23:09
更新:最终实现代码
作者: 灰白君    时间: 2018-1-6 08:23
顶,我爱你
作者: IO0294    时间: 2018-1-11 00:28
感谢分享
作者: SyouLynn    时间: 2019-5-19 21:33
谢谢大大
作者: guidayu    时间: 2019-7-26 16:58
真的非常感动,有大大这样热心的人,不然真不知道该怎么学了
作者: meng133692    时间: 2019-8-27 17:55
请问下这种窗口怎么隐藏和修改窗口的大小以后它不会自己刷新怎么弄
作者: 天空娃娃    时间: 2019-9-13 18:24
请问大大刷新窗口是哪段代码呀...
作者: xjzsq    时间: 2019-10-4 14:34
天空娃娃 发表于 2019-9-13 18:24
请问大大刷新窗口是哪段代码呀...

刷新窗口是Window_MapStatus.prototype.update这个函数。
目前应该是还没有讲到(因为写到最后烂尾了,不过近期准备继续完善)
作者: xjzsq    时间: 2019-10-4 14:40
meng133692 发表于 2019-8-27 17:55
请问下这种窗口怎么隐藏和修改窗口的大小以后它不会自己刷新怎么弄

隐藏的话,你修改一下Window_MapStatus.prototype.update函数,当满足某种条件的时候把窗口的透明度改成0:this.contentsOpacity = 0;
修改窗口大小的话,改一下this._StatusWindow = new Window_MapStatus(0, 0, 410, 216);这行代码中后两个数字即可,一个是x,一个是y,但是元素不会跟着放大,需要同时调整元素绘制的时候的坐标值
作者: 织梦行云    时间: 2019-11-1 15:37
支持一波!!!!
作者: 织梦行云    时间: 2019-11-1 16:30
楼主,你的汉化版js文件怎么下的,我的别说汉化,连个注释都没有,很坑
作者: 织梦行云    时间: 2019-11-1 16:37
大佬,汉化版的RMMV js库有吗,我找不到。
作者: meng133692    时间: 2019-11-3 21:51
xjzsq 发表于 2019-10-4 14:40
隐藏的话,你修改一下Window_MapStatus.prototype.update函数,当满足某种条件的时候把窗口的透明度改成0 ...

你好可以给个例子吗?我加入了那条代码并没有透明
作者: xjzsq    时间: 2019-11-16 03:33
织梦行云 发表于 2019-11-1 16:30
楼主,你的汉化版js文件怎么下的,我的别说汉化,连个注释都没有,很坑

我在注意事项第1条那里已经放上下载链接了...
我再放一次吧:https://github.com/wangwangxinga ... /%E6%B3%A8%E9%87%8A
作者: xjzsq    时间: 2019-11-16 03:37
meng133692 发表于 2019-11-3 21:51
你好可以给个例子吗?我加入了那条代码并没有透明

窗口更新对应的是这些代码:(作用是刷新窗口,如果角色走到窗口上的话,就把窗口的透明度改为75)
  1. Window_MapStatus.prototype.update = function () {
  2.     Window_Base.prototype.update.call(this);
  3.     if($refresh){
  4.         this.refresh();
  5.         $refresh = false;
  6.     }
  7.     if ($gamePlayer.screenX() >= 0 && $gamePlayer.screenX() <= this.width && $gamePlayer.screenY() >= 0 && $gamePlayer.screenY() <= this.height)
  8.     {
  9.         this.contentsOpacity = 75;
  10.     }
  11.     else this.contentsOpacity = 225;
  12. }
复制代码

按照您的要求的话,只要在if里面加上需要透明的条件,并把上面的75改成0即可。
作者: 815738927    时间: 2019-11-16 07:02
学到了,谢谢大佬
作者: 7479958    时间: 2022-6-8 00:17
看的真过瘾,虽然不懂代码
作者: Aistv    时间: 2024-4-1 13:30
考古 学会鸟




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