设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2223|回复: 1
打印 上一主题 下一主题

[原创发布] 【教程】制作一个Mogeko Castle式的菜单界面

[复制链接]

Lv5.捕梦者 (暗夜天使)

只有笨蛋才会看到

梦石
1
星屑
21040
在线时间
9341 小时
注册时间
2012-6-19
帖子
7107

开拓者短篇九导演组冠军

跳转到指定楼层
1
发表于 2022-4-19 00:05:42 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 喵呜喵5 于 2022-4-19 00:08 编辑

庆祝我的博客搬家,把我七年前写了一半的教程写完了……

访问我的博客获得更好的阅读体验 https://script.miaowm5.com/post/93

引言


前一段时间玩了海底囚人的 Mogeko Castle ,虽然电波对不上玩起来感觉有点微妙,但是这个游戏使用的菜单还是有点意思的。因此,打算写一个简单的教程介绍一下如何使用RMVA制作出这样的菜单。请注意,下面的教程要求你有一定的脚本基础,整个教程我更多的是说明我写这个脚本时的思路而不是为什么可以这么写,因此……嘛。
首先先放上游戏菜单的截图:


另外,随着游戏进程的推进或者游戏中加入新角色时,菜单中的立绘和人物信息还会发生改变,例如下面这样:


大概搞懂了需求以后,下面就开始开心的写代码吧。

调整已有逻辑


首先,先在 Window_MenuCommand 中删除菜单不需要的选项。
这里保留了 add_original_commands 以增强和其他菜单添加选项脚本的兼容性。
RUBY 代码复制
  1. class Window_MenuCommand
  2.   def make_command_list
  3.     add_command(Vocab::item, :item)
  4.     add_original_commands
  5.     add_save_command
  6.     add_game_end_command
  7.   end
  8. end

接着,进入到 Scene_Menu 中,把不需要的右侧队友状态窗口删除。
RUBY 代码复制
  1. class Scene_Menu
  2.   def create_status_window
  3.   end
  4. end

注意到原本的菜单中这两个窗口并不是仅仅贴着屏幕边缘而是和其有一小段距离的,在 start 的最后将这两个窗口的位置稍微移动一些。
RUBY 代码复制
  1. class Scene_Menu
  2.   alias m5_20150301_start start
  3.   def start
  4.     m5_20150301_start
  5.     @command_window.x += 6
  6.     @command_window.y += 6
  7.     @gold_window.x += 6
  8.     @gold_window.y -= 6
  9.   end
  10. end


队伍成员窗口


下面开始制作显示当前队伍成员的窗口,新建一个 Window_Base 的子类,起一个不容易冲突的名字 Window_M5ActorStatus20150301。最开始先要快速测试窗口是否正常显示,因此先把随便把位置定在 200,200,大小设置为 160*100
RUBY 代码复制
  1. class Window_M5ActorStatus20150301 < Window_Base
  2.   def initialize
  3.     super(200,200,160,100)
  4.   end
  5. end

将上述窗口加到 Scene_Menu 中
RUBY 代码复制
  1. class Scene_Menu
  2.   alias m5_20150301_start start
  3.   def start
  4.     m5_20150301_start
  5.     @command_window.x += 6
  6.     @command_window.y += 6
  7.     @gold_window.x += 6
  8.     @gold_window.y -= 6
  9.     @m5_20220418_actor_window = Window_M5ActorStatus20150301.new
  10.   end
  11. end

总体来看似乎没有什么大问题,接下去就开始为窗口内部描绘内容了。先从描绘队伍中第一个角色开始。重新修改 Window_M5ActorStatus20150301 添加描绘行走图和名字的代码。
同时,根据游戏内实际的表现,开始细调内容的位置和窗口的尺寸位置。最终的窗口大小为 160*70,位置为 6,286。
RUBY 代码复制
  1. class Window_M5ActorStatus20150301 < Window_Base
  2.   def initialize
  3.     x = 6
  4.     y = 286
  5.     width = 160
  6.     height = 70
  7.     actor = $game_party.leader
  8.     super(x,y,width,height)
  9.     refresh(actor)
  10.   end
  11.   def refresh(actor)
  12.     contents.clear
  13.     draw_actor_graphic(actor, 20, 40)
  14.     draw_text(0, 0, contents_width, line_height, actor.name, 2)
  15.   end
  16. end

第一个角色调通后,下面该开始根据队伍中的实际数据显示角色了。重新改写 Window_M5ActorStatus20150301 的代码
RUBY 代码复制
  1. class Window_M5ActorStatus20150301 < Window_Base
  2.   def initialize(actor, index)
  3.     x = 6
  4.     y = 286 - index * ( 70 + 5 )
  5.     width = 160
  6.     height = 70
  7.     super(x,y,width,height)
  8.     refresh(actor)
  9.   end
  10.   def refresh(actor)
  11.     contents.clear
  12.     draw_actor_graphic(actor, 20, 40)
  13.     draw_text(0, 0, contents_width, line_height, actor.name, 2)
  14.   end
  15. end

Window_M5ActorStatus20150301 里,窗口的 y 坐标从固定的286改成第一个窗口286,第二个窗口286-70+5,第三个窗口286-(70+5)*2……依次类推。(70 是窗口的高度,5 是窗口和窗口的间距。)窗口描绘的角色也从固定的 $game_party.leader 修改成了通过参数传递。
接下来,修改 Scene_Menu ,将 Window_M5ActorStatus20150301 所需的 actor 和 index 传递进去。
RUBY 代码复制
  1. class Scene_Menu
  2.   alias m5_20150301_start start
  3.   def start
  4.     m5_20150301_start
  5.     @command_window.x += 6
  6.     @command_window.y += 6
  7.     @gold_window.x += 6
  8.     @gold_window.y -= 6
  9.     @m5_20220418_actor_window = $game_party.all_members.slice(0,3)
  10.       .reverse.collect.each_with_index do |actor, index|
  11.         Window_M5ActorStatus20150301.new(actor, index)
  12.       end
  13.   end
  14.   instance_methods(false).include?(:terminate) ||
  15.     (def terminate *args; super; end)
  16.   alias m5_20220418_terminate terminate
  17.   def terminate
  18.     m5_20220418_terminate
  19.     @m5_20220418_actor_window.each(&:dispose)
  20.   end
  21. end

……似乎写了一段很吓人的代码,我们一点点分析这次做出的改动。
  1. @m5_20220418_actor_window = $game_party.all_members.slice(0,3)
  2.   .reverse.collect.each_with_index do |actor, index|
  3.     Window_M5ActorStatus20150301.new(actor, index)
  4.   end
复制代码

@m5_20220418_actor_window 不再是窗口了,现在变成了一个数组。我们先通过 $game_party.all_members 获取到当前队伍中全部的角色,再通过 slice(0,3) 选择前三个角色,之后,使用 reverse 方法反转顺序,最后使用 collect 方法将每个角色作为参数传递给 Window_M5ActorStatus20150301,最终返回的窗口被放入了数组中。通过上面这一串操作,最终成功达成了根据队伍中当前成员情况动态创建窗口的目的。
同时,因为 @m5_20220418_actor_window 不再是窗口而是数组了,数组中的窗口不再会自动释放了,因此,我们需要手动在界面关闭时调用每个窗口的 dispose 方法
  1. alias m5_20220418_terminate terminate
  2. def terminate
  3.   m5_20220418_terminate
  4.   @m5_20220418_actor_window.each(&:dispose)
  5. end
复制代码

另外,在默认脚本中 Scene_Menu 并没有定义 terminate 方法,出于 alias 的兼容性考虑,我们还需要显式的定义一下。
  1. instance_methods(false).include?(:terminate) ||
  2.   (def terminate *args; super; end)
复制代码

大功告成!

立绘展示


完成了角色信息弹窗,接下来就开始写界面右侧立绘展示的代码了。在开始写代码之前我们先规划一下这个功能的设计。对于角色立绘的展示,我们打算换一种方式,直接根据 变量1 的值确定立绘显示的内容。
我们先准备素材,这次的素材选择的是 MtU@ついった 老师画的结月缘,为了方便对坐标,这次直接将素材尺寸处理成屏幕的 544*416 大小,将素材放到 Graphics/Pictures/menu_actor 下面。
接下来,继续改写 Scene_Menu ,加上用于显示立绘的 Sprite 的创建和释放代码。
  1. class Scene_Menu
  2.   def start
  3.     m5_20150301_start
  4.     @command_window.x += 6
  5.     @command_window.y += 6
  6.     @gold_window.x += 6
  7.     @gold_window.y -= 6
  8.     @m5_20220418_actor_window = $game_party.all_members.slice(0,3)
  9.       .reverse.collect.each_with_index do |actor, index|
  10.         Window_M5ActorStatus20150301.new(actor, index)
  11.       end
  12.     @m5_20220418_actor_sprite = Sprite.new
  13.     @m5_20220418_actor_sprite.bitmap = Cache.picture('menu_actor/0')
  14.   end
  15.   def terminate
  16.     m5_20220418_terminate
  17.     @m5_20220418_actor_window.each(&:dispose)
  18.     @m5_20220418_actor_sprite.dispose
  19.   end
  20. end
复制代码

显示正常了,接下来就改写代码,让图片能够根据变量1的值动态的显示不同的立绘吧。
  1. @m5_20220418_actor_sprite.bitmap = Cache.picture("menu_actor/#{$game_variables[1]}")
复制代码

大功告成!

最终成品


RUBY 代码复制
  1. class Window_MenuCommand
  2.   def make_command_list
  3.     add_command(Vocab::item, :item)
  4.     add_original_commands
  5.     add_save_command
  6.     add_game_end_command
  7.   end
  8. end
  9. class Scene_Menu
  10.   alias m5_20150301_start start
  11.   def start
  12.     m5_20150301_start
  13.     @command_window.x += 6
  14.     @command_window.y += 6
  15.     @gold_window.x += 6
  16.     @gold_window.y -= 6
  17.     @m5_20220418_actor_window = $game_party.all_members.slice(0,3)
  18.       .reverse.collect.each_with_index do |actor, index|
  19.         Window_M5ActorStatus20150301.new(actor, index)
  20.       end
  21.     @m5_20220418_actor_sprite = Sprite.new
  22.     @m5_20220418_actor_sprite.bitmap = Cache.picture("menu_actor/#{$game_variables[1]}")
  23.   end
  24.   def create_status_window
  25.   end
  26.   instance_methods(false).include?(:terminate) ||
  27.     (def terminate *args; super; end)
  28.   alias m5_20220418_terminate terminate
  29.   def terminate
  30.     m5_20220418_terminate
  31.     @m5_20220418_actor_window.each(&:dispose)
  32.     @m5_20220418_actor_sprite.dispose
  33.   end
  34. end
  35. class Window_M5ActorStatus20150301 < Window_Base
  36.   def initialize(actor, index)
  37.     x = 6
  38.     y = 286 - index * ( 70 + 5 )
  39.     width = 160
  40.     height = 70
  41.     super(x,y,width,height)
  42.     refresh(actor)
  43.   end
  44.   def refresh(actor)
  45.     contents.clear
  46.     draw_actor_graphic(actor, 20, 40)
  47.     draw_text(0, 0, contents_width, line_height, actor.name, 2)
  48.   end
  49. end

评分

参与人数 4星屑 +666 +4 收起 理由
yz3440080 + 1
Kim_Shyuen + 1
hyrious + 1 喵喵喵
alexncf125 + 666 + 1 精品文章

查看全部评分

Lv4.逐梦者

梦石
0
星屑
10715
在线时间
2028 小时
注册时间
2013-6-10
帖子
1498
2
发表于 2022-4-19 08:11:18 | 只看该作者
太优秀了
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-5-16 18:30

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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