设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
返回列表
+ 发新帖
查看: 977|回复: 0

[转载发布] [教程]RMMV脚本教程——菜单美化(三)(完结)

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    昨天 03:27
  • 签到天数: 222 天

    连续签到: 1 天

    [LV.7]常住居民III

    9102

    主题

    893

    回帖

    7万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    64916
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    74941

    灌水之王

    发表于 2024-3-4 03:07:58 | 显示全部楼层 |阅读模式
    前两期教程的传送门

    写在前面
    时隔不到一年半,高考完的我终于决定继续研究MV的脚本,然后写教程啦…
    之前的教程(下面参考资料有文章链接)发布在Project1(原6R)论坛上,之前的坑还是会慢慢填完的,现在再开个新坑!
    这次来美化一下菜单!
    首先放一下先行图:






    注意事项

    正文
    上期教程,我们写好了人物行走图选项的部分,下面就实现中间显示人物的信息,并且信息会随着选项的位置改变的效果。
    还记得我在之前写烂尾的教程(在注意事项第三条3那里)里面如何描绘人物信息的吗?(回去看了看,貌似只写到了描绘人物名字的部分)
    我们这次为了代码简单一些,就不描边了。
    因为随选项而使人物信息变化比较难,所以我们就先把index==0的角色信息描绘出来,像描绘角色行走图一样,我们需要新建一个函数,把所有关于描绘角色信息的代码都写在这个函数里,仿照drawItemImage,新函数就叫做drawItemActorStatus,具体方法也参照drawItemImage来写:

    这里,rect的y和height并不能满足要求,因此,这里珂以参照itemRect函数自己写一个返回rect方法,这里叫做itemRectForStatus,也是将itemRect中的内容复制过来,再做进一步修改。新定义的这个函数有什么不同呢?首先是他和人物的index无关了,所以这个函数就没有参数了;其次是他的rect.y应该先加上一个选项的高度,而rect.heigtht应该为原来基础上的5(this.numVisibleRows() - 2)倍,按照上面说的写出以下函数:

    之后,将drawItemActorStatus中的itemRect函数改为itemRectForStatus。
    要描绘人物的脸图,使用的方法是drawActorFace,参数珂以对照着Window_MenuStatus的drawItemImage函数里面的drawActorFace的参数来填,也就是下面这样:

    先运行下测试一下看看是否正常显示吧,不过在测试之前,我们需要将drawItemActorStatus函数先写到Window_MenuStatus的drawItem函数里面,也就是在里面加上:

    之后运行看下结果吧!
    如果在菜单中显示了第一个人物的脸图,那你就写对了。
    在这以后,我们就来描绘剩下的东西。
    首先是在脸图上面描绘人物名字,使用的是drawActorName函数,定义在Window_Base中,参数珂以去看定义,这里需要说明的是,有些参数珂以不填,比如看到drawActorName函数的定义:

    其中width = width || 168; 就表示width是一个可填可不填的参数,就算不填,也会自动给补上,这里我们是想在脸图上方描绘名字,而脸图的宽度是144(珂以去脸图目录下的文件那里看宽度/4就是这个数字),而按照默认宽度,珂能会出现绘制到脸图外面的情况,因此我们填上这个参数。
    也就是:

    同样,在Window_Base中,我们珂以搜索到绘制角色等级、职业、昵称、HP、MP的函数,因为图像的宽度是144,因此描绘这些的时候,x都需要在原来的基础上加145;等级这一行,珂以先算出( rect.width - 144 ) / 3的结果为_valWidth,然后描绘职业和昵称的时候,分别在x那里加上一个或两个_valWidth;另外,在MV中每行字的高度是36,描绘的每个项目都要加上宽度,第一行是_valWidth,后面都是rect.width - 144。珂以写出以下代码:

    MV默认工程里面,人物是没有昵称的,我们需要去数据库里加上昵称,然后运行测试下效果。
    …是不是发现等级那里有点不对劲…
    数字离着Lv符号太远了…
    那我们就重新定义下等级的函数,同样是从Window_Base中复制过来,然后把数字往左放一点(也就是把drawText的x值改小一点,这里改成了x + 48,因为上面的等级符号宽度是48):运行下看结果:


    下面就开始写经验条了,因为MV脚本没有自带描绘经验条的函数,这就需要我们自己来写…
    仿照HP条来写经验条吧。
    我们先在Window_Base中找到描绘HP条的方法:

    第一行,是默认的宽度,这个不管。
    之后两行是两个颜色,为了区别于HP条,经验条就用TP条的颜色吧。
    第四行就是描绘HP条了,这里actor.hpRate()看起来控制了HP条有颜色部分的长度,我们应该把这个改成exp的,这个MV也没有自带,也需要自己写…同样找到这个的定义,但是根据actor来看,这应该是actor的属性,而actor应该是Game开头的代码里面定义的,但是我们不知道具体是在哪个类里面定义的,因此去游戏工程的脚本目录下的rpg_objects.js中搜索:

    发现是在Game_BattlerBase里面定义的,于是仿照这个函数在相同的类中定义expRate,当前的经验和下个等级所需的经验,这里直接给出来,为this.currentExp()和this.nextLevelExp(),写出以下函数:

    现在就珂以写drawActorExp函数了!还需要做的修改有单位改为expA,下面的数值改为当前经验和下等级经验,以及颜色改为tpColor :


    最后在drawItemActorStatus中加上描绘exp的函数:只剩下能力值和武器情况的描绘了。
    状态那里面是不是也描绘有这些东西?
    因此我们就去看看那里是怎么描绘的,打开rpg_window中的Window_Status,珂以搜到以下内容:
    这两个函数一个用来绘制能力值信息,一个用来描绘装备的信息,因此我们用这两个函数来绘制剩下的内容,因为这两个函数定义在Window_Status中,所以需要把这两个函数复制到Window_MenuStatus中,并修改成Window_MenuStatus中的函数;之后,在drawItemActorStatus中进行引用:
    改好后运行去发现提示param未定义,这并不说明是param的问题,反而是他前面的this._actor的问题:this._actor在Window_MenuStatus中是未定义的,因此需要改成用参数传递,再次运行测试前先记得在drawItemActorStatus的函数调用那里补上参数actor。
    再次运行,发现this.maxEquipmentLines()未定义,这还是需要从Window_Status中去复制。
    最终得到以下代码:
    最终测试得到以下画面:

    下面就开始实现人物信息随选项变动的功能了!
    首先,我们需要知道存储当前选项的变量是什么,在Window_MenuStatus中的处理确定的函数processOk中,获取当前的人物是通过this.index()实现的,而this.index()呢?在Window_MenuStatus中没有搜到这个函数的定义,因此我们去他的父类Window_Selectable中搜索,得到以下结果:

    因此我们也珂以使用this._index获取当前index。
    因此将index那里改为this._index,然后运行下看看效果。
    运行后却得到了TypeError: Cannot read property 'faceName' of undefined的错误。
    难道说this._index出错了?我们珂以看看到底运行到这里this._index返回了什么值。
    这就要用到浏览器的控制台输出函数,在出错的这行前面插入:

    再次运行打开菜单出错后按F12,发现输出的值为-1,为什么是-1?我们现在他等于-1的时候把值改为0,然后在F12里面看看这个-1是什么情况下出现的。
    因此将定义actor那行改为:

    却发现F12在选项移动的过程中并没有输出任何东西,说明drawItemActorStatus这个函数在选项移动过程中并没有被调用,只是绘制选项的过程中被调用了一次,这显然达不到我们的要求。
    这里补充一个知识:放在窗口类的update函数内的函数会不断被调用。而Window_MenuStatus中没有定义update函数,说明他的update与父类相同,因此需要自己定义update函数(首先继承了父类的update函数):

    并且记得在drawItem中删掉drawItemActorStatus函数的引用。
    然后运行后发现,虽然人物信息随着选项的移动而改变,但是却发现原来的人物信息还在,只是往窗口上一层一层地“铺”,这样肯定是不行的。
    因此我们需要想办法,让原人物信息先从菜单上清除,再描绘当前选项的人物信息。
    Tip:清除坐标为x,y,高和宽分别为height和width的矩形中的内容的函数为clearRect,我们珂以通过itemRectForStatus函数来获得矩形的信息,同样把下面这行插入update:

    运行下看看结果……
    确实是没问题了。但是不知为啥电脑风扇开始狂转,打开任务管理器,发现MV的生成的游戏的进程电池使用情况为“非常高”(写教程的时候电脑开着这个时候的游戏开了一晚上,早晨起来发现电脑风扇快转疯了……),这肯定不正常啊…
    打开F12发现,之前写的输出this._index的代码正在疯狂输出-1,说明画面更新实在是太频繁了,而实际上并不需要这么频繁,只需要在选项变化的时候更新画面即可。
    怎样判断选项变化呢?
    因为this._index存储了当前的选项,所以只要选项和原来不一样,this._index就会和原来不一样,所以珂以先把this._index的值存到一个变量中,如果两者不相等,再执行清除重绘的函数,并更新存储的变量,这样就珂以解决因为频繁刷新而导致电脑卡到爆的情况了。
    我们在update函数外面新建一个变量xjzsqIndex,然后在update函数内增加一个if判断,来实现这个效果,并且记得把在控制台输出this._index值的那句删掉!代码如下:

    电池使用情况立马变成“中”了。
    现在就只剩下改变菜单背景了吧。
    在加上自带的背景图片之前,我们先把窗口自带的边框“扒”掉,虽然说是扒掉,但是方法确实将窗口背景部分的内容透明度更改为0。
    比较合适的修改窗口透明度的时机有两个,一个是在窗口的initialize中修改,因为这是窗口的初始化过程,只执行一次,不会因为多次执行浪费计算资源,另一种是在使用new创建窗口的时候修改,具体在哪里修改还是要看具体情况,哪个方便就在哪里改。
    首先是显示金钱的窗口,因为我们在脚本中定义过Scene_Menu的createGoldWindow函数,因此珂以在金钱窗口创造后使用

    来将金钱窗口背景的透明度修改为0。
    对于菜单选项窗口,我们考虑在initialize函数中修改透明度,但是我们发现initialize中已经有了其他方法,我们珂以通过重写这个方法,也就是:(具体为什么这样写珂以去看我参考资料中的烂尾教程一)

    但是我希望代码尽量短一些,所以我决定在refresh中修改透明度,原因是,refresh函数在该函数中并没有定义,而是直接继承的父类的refresh中的内容,我们自己重新定义比较方便,另外refresh函数也只在他的父类的initialize函数中被调用了一次,本质上还是在initialize中修改的。
    因此我们珂以用比上面少一行的代码量来修改复杂度:

    同样地,经过搜索,发现Window_MenuStatus情况也大致相同,因此采用与上面同样的方法:

    运行游戏测试一下:


    所有的窗口背景都消失了!
    下面我们就插入背景图片吧!
    首先大家先把我们用到的图片下载下来:




    下载链接:MenuBackground
    下载好以后放到工程目录的/img/system文件夹下(当然你放到其他文件夹也是珂以的,只是后面显示图片的函数会有所区别)
    然后我们再次打开Scene_Menu,既然是背景,那就搜索background大概就行了吧,但是竟然没搜到…什么情况?难道默认没有这个函数吗?还不能轻易下结论,注意看Scene_Menu的父类,是Scene_MenuBase,名字就说明这个类也是专门为了菜单设置的,因此我们打开Scene_MenuBase,再次搜索找到以下函数:

    这大概是实现在地图上截图并以此作为菜单背景的代码,因此我们珂以在Scene_Menu中重写这个函数,在父类的基础上增加显示我们刚才下载的那张图片。
    首先也仿照Scene_MenuBase的createBackground函数创造一个精灵,就叫做_backgroundSprite2吧;然后指定这个精灵的位图,这里的位图,我们通过ImageManager.loadSystem("文件名"),来读取/img/system目录下文件名为”文件名.png“的文件;最后也是将精灵添加到屏幕上,代码如下:

    运行测试一下效果:


    到这里,教程的基础部分就结束啦!

    代码下面的附件是为了求糖,内容和上面代码框里的一致。
    xjzsqMenu.zip(1.9 KB, 下载次数: 8, 售价: 100 星屑)2019-7-17 00:48 上传
    点击文件名下载附件
    完整代码文件
    售价: 100 星屑         [记录]   [购买]  


    然后是工程文件:(请下载解压后直接覆盖粘贴到一个RMMV新建的游戏工程文件夹内,以补全缺少的文件)
    MenuGuide.zip(485.16 KB, 下载次数: 7, 售价: 100 星屑)2019-7-17 01:18 上传
    点击文件名下载附件
    游戏工程
    售价: 100 星屑         [记录]   [购买]  



    作业
    作业布置什么好呢?
    就在菜单的人物信息那里的人物头像下方,显示能力值的位置上方,增加人物当前状态图标(睡眠、中毒等图标)的显示吧!
    至于如何显示状态图标,这个就通过自己搜索得知啦!
    这次的作业将会在Project1论坛的2L公布答案。


    后记
    从7.2发第一期,到现在(7.16)已经过了两周了。
    在写教程的过程中,我也不断发现自己原来写好的脚本存在的写的不合理或者不优雅的地方,很多原来不是很明白的地方也因为写教程要讲明白所以理解地更加透彻了,也许这就是《礼记》中所说的“教学相长吧”。
    下次写教程不知道会是什么时候了,计划是讲解一下官方自带的插件或者其他用的比较多的插件是怎么写出来的,也可能是对MV本身自带脚本的解读,总之敬请期待,请大家多多包涵啦!感谢大家的大力支持!








                 本帖来自P1论坛作者xjzsq,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=478030  若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x

    帖子地址: 

    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-10-22 02:21 , Processed in 0.118393 second(s), 55 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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