如何优雅的研究 RGSS3 (三) 调整窗口的细节

在上一期我们研究了向窗口中添加选项的方法,本期就来研究一下窗口类的具体细节。

所有窗口的父类 Window_Base 初始化时需要四个参数。

  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize(x, y, width, height)
    super
    self.windowskin = Cache.system("Window")
    update_padding
    update_tone
    create_contents
    @opening = @closing = false
  end

这四个参数表示窗口左上角的横纵坐标以及窗口的宽度与高度。

Window_Base 中还提供了绘制窗口的一整套方法。

比如说绘制文本(draw_text)、 绘制值槽(draw_gauge)、绘制图标(draw_icon)、绘制角色肖像图(draw_face)等等。

Window_Selectable 是拥有光标移动、滚动功能的窗口的父类。

其中定义了一些获得窗口中的绘制项目所需信息的方法。

比如获取列数(col_max)、获取行间距的宽度(spacing)、获取项目的宽度(item_width)等等。

Window_Selectable 类中还定义了处理光标在项目中移动以及选择的方法。

比如处理光标的移动(process_cursor_move)、“确定”和“取消”的处理(process_handling)等等。

Window_Command 的使用方法上一期已经讲过了,它还有一个子类,Window_HorzCommand 表示可以横向选择的指令窗口。

只要是继承自 Window_HorzCommand 的指令装口就是横向选择的。

我们发现虽然指令窗口可以横向选择,但是 Window_Selectable 的子类却只能纵向选择。

所以现在参照 Window_HorzCommand 写一个 Window_HorzSelectable 来处理横向选择的窗口。

#encoding:utf-8
#==============================================================================
# ■ Window_HorzSelectable
#------------------------------------------------------------------------------
#  拥有横向光标移动、滚动功能的窗口
#==============================================================================

class Window_HorzSelectable < Window_Selectable

横向与纵向的窗口区别有:

纵向窗口使用上下键切换选项;横向窗口使用左右键切换选项。

选项数量超过一页能显示的最大数量时,纵向窗口的上下边界会有三角箭头,而横向窗口的左右边界有三角箭头。

纵向窗口的选项是从起点向下绘制的;横向窗口的选项是从起点向右绘制的。

参考 Window_HorzCommand  将 Window_Selectable 中与以上三种区别有关的方法挑选出来在 Window_HorzSelectable 中重写。

  #--------------------------------------------------------------------------
  # ● 获取列数
  #--------------------------------------------------------------------------
  def col_max
    return 4
  end
  #--------------------------------------------------------------------------
  # ● 获取行间距的宽度
  #--------------------------------------------------------------------------
  def spacing
    return 8
  end

  #--------------------------------------------------------------------------
  # ● 获取首列位置
  #--------------------------------------------------------------------------
  def top_col
    ox / (item_width + spacing)
  end
  #--------------------------------------------------------------------------
  # ● 设置首列位置
  #--------------------------------------------------------------------------
  def top_col=(col)
    col = 0 if col < 0
    col = col_max - 1 if col > col_max - 1
    self.ox = col * (item_width + spacing)
  end
  #--------------------------------------------------------------------------
  # ● 获取尾列位置
  #--------------------------------------------------------------------------
  def bottom_col
    top_col + col_max - 1
  end
  #--------------------------------------------------------------------------
  # ● 设置尾列位置
  #--------------------------------------------------------------------------
  def bottom_col=(col)
    self.top_col = col - (col_max - 1)
  end

  #--------------------------------------------------------------------------
  # ● 确保光标在画面范围内滚动
  #--------------------------------------------------------------------------
  def ensure_cursor_visible
    self.top_col = index if index < top_col
    self.bottom_col = index if index > bottom_col
  end

  #--------------------------------------------------------------------------
  # ● 计算窗口内容的宽度
  #--------------------------------------------------------------------------
  def contents_width
    (item_width + spacing) * item_max - spacing
  end
  #--------------------------------------------------------------------------
  # ● 计算窗口内容的高度
  #--------------------------------------------------------------------------
  def contents_height
    item_height
  end

  #--------------------------------------------------------------------------
  # ● 获取项目的绘制矩形
  #--------------------------------------------------------------------------
  def item_rect(index)
    rect = super
    rect.x = index * (item_width + spacing)
    rect.y = 0
    rect
  end

  #--------------------------------------------------------------------------
  # ● 光标向下移动
  #--------------------------------------------------------------------------
  def cursor_down(wrap = false)
  end
  #--------------------------------------------------------------------------
  # ● 光标向上移动
  #--------------------------------------------------------------------------
  def cursor_up(wrap = false)
  end

  #--------------------------------------------------------------------------
  # ● 光标移至下一页
  #--------------------------------------------------------------------------
  def cursor_pagedown
  end
  #--------------------------------------------------------------------------
  # ● 光标移至上一页
  #--------------------------------------------------------------------------
  def cursor_pageup
  end

end

虽然 Window_Selectable 默认的是纵向选择的窗口,但是实际上其中定义了上下左右四个键的行为,并用 row_max 与 col_max 方法来控制行数与列数, 只要改变这两个值就可以将它扩展为n*m的任意选择的窗口。

index 是用来表示选项编号的变量,它可以通过很简单的公式与选项的行列号进行换算。

col = inex % col_max、row = index / col_max

这里我们设置一行最多4列,当索引超出当前的4列时,就需要 ensure_cursor_visible 方法来改变首列和尾列,使光标在画面范围内滚动。

top_col=(col) 等方法其实很坑,重载的=操作符改变了参数index的值,这不符合常理。

最后我们用空的方法替换了光标上下移动以及翻页的方法。这样就只能用左右键来切换选项了。

最后来把游戏菜单画面改为横向吧。

这是默认的菜单画面:

Scene_Menu 中有三个窗口,排除金币窗口,菜单画面中显示指令的窗口与显示队伍成员状态的窗口都可以改为横向。

Window_MenuCommand 继承自 Window_Command,现在把它的父类改为 Window_HorzCommand。

然后修改一下 Window_MenuCommand 的窗口大小。

  #--------------------------------------------------------------------------
  # ● 获取列数
  #--------------------------------------------------------------------------
  def col_max
    return 7
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口的高度
  #--------------------------------------------------------------------------
  def window_height
    return 48
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口的宽度
  #--------------------------------------------------------------------------
  def window_width
    return Graphics.width
  end

将窗口宽度改为与游戏窗口的宽度相同,高度为48,考虑到共有7个选项,将最大列数设为7。

Window_MenuStatus 原本是 Window_Selectable 的子类,现在它的父类改为 Window_HorzSelectable。

接下来还是修改窗口的宽度与高度。

  #--------------------------------------------------------------------------
  # ● 获取窗口的宽度
  #--------------------------------------------------------------------------
  def window_width
    Graphics.width
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口的高度
  #--------------------------------------------------------------------------
  def window_height
    Graphics.height - 96
  end

虽然 Window_MenuStatus 的大小正确了,但是它的起点不对。

在 Scene_Menu 把窗口的起始坐标初始化成正确的值。

  #--------------------------------------------------------------------------
  # ● 生成状态窗口
  #--------------------------------------------------------------------------
  def create_status_window
    @status_window = Window_MenuStatus.new(0, 48)
  end

现在整体窗口框架已经正确,但是状态窗口中角色属性的绘制还没有变。

  #--------------------------------------------------------------------------
  # ● 绘制项目
  #--------------------------------------------------------------------------
  def draw_item(index)
    actor = $game_party.members[index]
    enabled = $game_party.battle_members.include?(actor)
    rect = item_rect(index)
    draw_item_background(index)
    draw_actor_face(actor, rect.x, rect.y, enabled)
    draw_actor_name(actor,rect.x, rect.y+96)
    draw_actor_class(actor,rect.x, rect.y+96+line_height*1)
    draw_actor_icons(actor,rect.x,rect.y+96+line_height*2)
    draw_actor_level(actor,rect.x, rect.y+96+line_height*2)
    draw_actor_hp(actor,rect.x, rect.y+96+line_height*3)
    draw_actor_mp(actor,rect.x,rect.y+96+line_height*4)
    draw_actor_tp(actor,rect.x,rect.y+96+line_height*5)
  end

用 Window_Base 中提供的工具绘制角色的属性。

最后调整一些细节参数。

最终成品:

如何优雅的研究 RGSS3 (三) 调整窗口的细节

时间: 2024-11-10 13:30:14

如何优雅的研究 RGSS3 (三) 调整窗口的细节的相关文章

如何优雅的研究 RGSS3 (四) 使窗口从画面边缘弹出

在很多游戏中,窗口可以从游戏画面的边缘弹出. 而在 RGSS3 的默认脚本中时没有这种功能的,当在地图上按下取消键时,游戏菜单会突然出现. 现在我们可以为主菜单添加动画效果,使其在屏幕边缘弹出. 我们知道游戏中的画面并不是真正的在动,而是在每一帧都绘制一幅新的画面. 每一帧都对画面做一些微小的改变,在玩家的眼里就会产生画面在运动的错觉. 复杂的运动效果涉及到复杂的公式,这里我们只采用最简单的匀速直线运动. 我们为主菜单中的三个窗口添加匀速直线的运动规律,使其从画面的边缘移动到目标位置. @com

如何优雅的研究 RGSS3 番外(二) 显示文字信息的窗口中的纤程

Ruby 中的 Fiber 通常称为纤程,是一种非抢占式的多线程模型. 纤程不能在外部被终止,只能等待其主动让出执行权. RGSS3 在事件解释器 Game_Interpreter 与显示文字信息的窗口 Window_Message 中都用到了纤程. 以 Window_Message 为例. #-------------------------------------------------------------------------- # ● 更新画面 #-----------------

如何优雅的研究 RGSS3 (五) 输入数字的画面

游戏中的名字输入画面是一个非常没有中国特色的场景. 我们知道英文不过26个字母,日语也只有几百个假名,但是汉字的数量实在是太多了,导致名字输入画面在汉化成中文版时只能用部分汉字来填充假名. 输入名字的功能并没有什么重要价值,但是这个功能实现的方法却值得我们研究. 游戏中有一个默认的输入数字的窗口,但是它非常不好用. 今天就来参照名字输入画面编写一个数字输入画面.用于玩家向游戏中输入数字. 涉及到名字输入画面的有三个类:Scene_Name.Window_NameEdit.Window_NameI

如何优雅的研究 RGSS3 (六) 技能与物品画面剖析

物品与技能画面剖析 物品画面和技能画面有共同的父类 Scene_ItemBase,而 Scene_ItemBase 继承自 Scene_MenuBase. Scene_ItemBase 在开始时用 create_actor_window 生成了显示角色的窗口备用. Scene_ItemBase 中定义了若干方法作为处理画面的工具. 其中 show_sub_window.hide_sub_window 可以显示.隐藏一个窗口. item.user用于获取选中的物品与使用者. on_actor_ok

如何优雅的研究 RGSS3 (七) 添加LOGO画面

为游戏添加 LOGO 画面. 首先要设计 LOGO 场景类,我们知道场景类都是 Scene_Base 的子类. 我们来回顾一下场景的工作原理. 首先执行开始处理,接着是开始后处理,然后是不停的更新画面,最后结束前处理,然后结束处理. 下面来逐个分析这些方法. 当进入 LOGO 画面时,显然不需要也不可能回到上一个画面,因此在开始处理的方法中,我们要清空场景的切换记录. 接下来要创建出需要显示的 LOGO 图片,但是不能让它立即显示,而是要使其淡入画面,因此要冻结住图像的显示. 最后播放 LOGO

如何优雅的研究 RGSS3 番外(一) ruby 实现的后缀自动机

*我真的不会 ruby 呀* #encoding:utf-8 #============================================================================== # ■ Suffix_Automaton #------------------------------------------------------------------------------ # 后缀自动机. #============================

怎样优雅的研究 RGSS3 番外(一) ruby 实现的后缀自己主动机

*我真的不会 ruby 呀* #encoding:utf-8 #============================================================================== # ■ Suffix_Automaton #------------------------------------------------------------------------------ # 后缀自己主动机. #==========================

Qt新渲染底层Scene Graph研究(三)

Qt新渲染底层Scene Graph研究(三) 上一篇文章介绍了Qt Quick和SceneGraph的一些理论上的内容.这也是我最新的研究成果.接下来我要介绍一下如何使用Scene Graph来制作一些好玩的效果.这也是我进行一次SceneGraph的尝试. 我的目标是希望在Scene Graph这一套渲染框架下实现一个带有纹理的立方体,并且旋转.花了几天,虽然不是那么满意,但是已经告一段落了. 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/articl

Qt 3D研究(三):显示3D模型

Qt 3D研究(三):显示3D模型 上一篇文章介绍了如何使用最少的代码创建一个Qt 3D的应用.和大家最初接触的glut一样,对于3D应用来说,需要做的准备工作还真不少,不过呢,Qt 3D把一些窗口相关的琐碎事情解决了,剩下的,该由我们完成重要的渲染部分了,可以说,带来了某种程度的方便. 蒋彩阳原创文章,首发地址:http://blog.csdn.net/gamesdev/article/details/43964499.欢迎同行前来探讨. 我们接下来要使用Qt 3D将一个模型显示出来.Qt 3