じ☆ve冰风 发表于 2024-4-19 21:13:59

ISA——支持子选项的选择窗口(理论支持无限层)

先上效果图(?):



比较鸡肋...
关于这个脚本的用法,稍后会发放范例(http://rpg.blue/thread-174282-1-1.html)

这张截图里面用的格式是:

    commands = ["dust",["a","b",["c","c1",["c1_1","c1_2","c1_3"]],"d","f"],"p"]
    @folder_window = Window_Folder.new(50,96,480,32*8,commands)

有点晕...?数组类(含子选项要求超过1个)会判定为"文件夹",该数组第2,3一直到最后1个会判定为
"子选项",当然,这些"子选项"还可以是"文件夹",以次类推

50,96,480,32*8 分别是x,y,宽,高

这个版本不是很完美,期待下个版本吧(不过极有可能TJ掉)

最后,上脚本(技术有限,比较臃肿...):#==============================================================================# ■ Window_Folder   ISA#------------------------------------------------------------------------------#  拥有光标的移动以及滚动功能、子项目的窗口类。#                        ISA#   制作       : 沙漠.灰#   本脚本版本 : v0.9   P.S : 制作中遇到了一个Bug,找了3个小时,不惜动用rescue#      最后发现是 if @folder_window.index = .....写成了 = 号了...##   本脚本很无敌(指的是Bug方面).欢迎各位朋友进行优化及DeBug#==============================================================================class Window_Folder < Window_Base#--------------------------------------------------------------------------# ● 定义实例变量#--------------------------------------------------------------------------attr_reader   :index                  # 光标位置attr_reader   :c                        # C 键允许#--------------------------------------------------------------------------# ● 初始画对像#   x      : 窗口的 X 坐标#   y      : 窗口的 Y 坐标#   width: 窗口的宽#   height : 窗口的高#--------------------------------------------------------------------------def initialize(x,y,width, height, commands)    super(x, y, width, height)    # 初始化数据    @move_to      = 0    @to_refresh   = false    @commands_size= 0    @c            = false    @index          =     @spread_command = []    @disable_item   = []    commands.size.times{@spread_command.push(1)}    @true_commands= commands    # 初始化所有项目    ini_command @true_commands    # 生成位图    self.contents = Bitmap.new(width - 32, @commands_size * 32)    v = Viewport.new(16+self.x, 16+self.y, width-32, height-32) ; v.z = 999    @new_bitmap = Sprite.new(v)    @new_bitmap.bitmap = Bitmap.new(width - 32, @commands_size * 32)    index = 0 # 描绘顶层项目    # 描绘父项目    for unit in @true_commands      # 描写项目      draw_command       # index 前进1      index += 1    endend#--------------------------------------------------------------------------# ● 初始化所有项目 array : 父项目#--------------------------------------------------------------------------def ini_command(array)    for unit in array      if unit.is_a?(Array)      unit.size > 1 ? ini_command(unit): @commands_size += 1      else      @commands_size += 1      end    endend#--------------------------------------------------------------------------# ● 项目无效化#   index : 项目编号#--------------------------------------------------------------------------def disable_item(index)    @disable_item.push(index)end#--------------------------------------------------------------------------# ● 指定项目是否为父项目 index 所在位置#--------------------------------------------------------------------------def is_folder?(commands,index)    # 若指定项目为数组且子单元数目大于1就判定为父项目    if index.size == 1 and commands].is_a?(Array)      return true if commands].size > 1    elsif index.size > 1      return is_folder?(commands],index)    end    # 否则就判定为非父项目    return falseend#--------------------------------------------------------------------------# ● 描绘项目名称 index 所在位置branch 是否分支#--------------------------------------------------------------------------def draw_command(index,branch=false)    # 查看当前index所在坐标    x, y = check_index_xy(index)    rect = Rect.new(x+32,y,self.width-32,32)    self.contents.font.color = disabled_color if @disable_item.include?(index)    name = get_command(@true_commands,index)    self.contents.draw_text(rect, name)    # 为父项目时,描绘指引    if is_folder?(@true_commands,index)      draw_flag(index,branch)    end    self.contents.font.color = normal_colorend#--------------------------------------------------------------------------# ● 取得项目名称 index 所在位置#--------------------------------------------------------------------------def get_command(name_array,index)    # 当index到底时(只有一个单元时)    return get_command_name(name_array]) if index.size == 1    # 没到底,删除首单元,继续调用自己    # 删除首单元?为嘛不用shift?   因为shift删除首单元,并返回它...    return get_command name_array],indexend#--------------------------------------------------------------------------# ● 再次 取得项目名称 index 所在位置#--------------------------------------------------------------------------def get_command_name(name_array)    if name_array.is_a?(String)      # 目前已经为字符串时,直接返回      return name_array    else      # 目前为数组且数组第X个还是数组时,调用并返回自己      if name_array.is_a?(Array)      return get_command_name(name_array)      else      # 第X个为字符串,直接返回      return name_array      end    endend#--------------------------------------------------------------------------# ● 描绘项目标记 index 所在位置#--------------------------------------------------------------------------def draw_flag(index,branch=false)    # 查看当前index所在坐标    x, y = check_index_xy index    src_rect= Rect.new(x+16,y+10,16,16)    # 清除原来标记    self.contents.fill_rect(src_rect, Color.new(0,0,0,0))    dest_rect = branch ? Rect.new(152, 40, 16, 16): Rect.new(168, 24, 16, 16)    src_bitmap= RPG::Cache.windowskin($game_system.windowskin_name)    # 图上现在标记    self.contents.stretch_blt(src_rect, src_bitmap, dest_rect)end#--------------------------------------------------------------------------# ● 检查 index 所在坐标#--------------------------------------------------------------------------def check_index_xy(index)    y = 0    # 检查项目   多1项,y+32    for i in 0...@spread_command.size      # 检查缩进项目,为数组时,进一步检查      if @spread_command.is_a?(Array)      # 在这个项目活动....      if index.size > 1            y += check_spread(@spread_command, index)      else          # 否则,加1行          y += 32      end      else      # 上次的没关闭,则自相加      #if @spread_command.is_a?(Array)          #y += @spread_command.self_all_plus * 32 - 32      #end      # 这个版本不支持↑,这里直接加32      y += 32#@spread_command * 32      end      break if index1          y += check_spread(spread_array,index)      else          # 否则,加1行          y += 32      end      else      # 上次的没关闭,则自相加      #if @spread_command.is_a?(Array)          #y += @spread_command.self_all_plus * 32 - 32      #end      # 这个版本不支持↑,这里直接加32      y += 32#@spread_command * 32      end      break if index1    return falseend#--------------------------------------------------------------------------# ● 刷新画面#--------------------------------------------------------------------------def update    super    move_command    return if @to_refresh != 0    # 可以移动光标的情况下    if self.active       # 方向键下被按下的情况下      if Input.repeat?(Input::DOWN)      $game_system.se_play($data_system.cursor_se)      # 跳跃到下一个同层选项      @index[-1] = (@index[-1]+1)%check_command_size(@index)      @index[-1] += 1 if @index.size > 1 and @index[-1] == 0      end      # 方向键上被按下的情况下      if Input.repeat?(Input::UP)      # 跳跃到上一个同层选项      $game_system.se_play($data_system.cursor_se)      # 跳跃到下一个同层选项      @index[-1] -= 1 if @index.size > 1 and @index[-1] == 1      @index[-1] = (@index[-1]-1)%check_command_size(@index)      end      # A键被按下的情况下      if Input.trigger?(Input::A)      # 展开\关闭 当前选项,展开优先      # 这个功能暂时被和谐掉...      #p @new_bitmap.x, @new_bitmap.y      end      # B键被按下的情况下      if Input.trigger?(Input::B)      # 退到上一层,若允许关闭,则关闭      if @index.size == 1          $game_system.se_play($data_system.buzzer_se)      else          @index.pop          $game_system.se_play($data_system.cancel_se)          # 允许关闭的情况下          folder(@index) # if $game_party.closed_by_b      end      end      # C键被按下的情况下      if Input.trigger?(Input::C)      @c = !is_folder?(@true_commands,@index)      # 展开当前选项,不能展开时,打开允许C键键入开关(否则关掉)      # 等待场景捕捉动作      if is_folder?(@true_commands,@index)          $game_system.se_play($data_system.decision_se)          folder(@index,false)      end      end    end    # 刷新光标矩形    update_cursor_rectend#--------------------------------------------------------------------------# ● 更新光标矩形#--------------------------------------------------------------------------def update_cursor_rect    x, y = check_index_xy(@index)    # 超出范围,更新self.oy    if y - self.oy >= self.height - 32      self.oy      += 32      @new_bitmap.oy += 32    elsif y - self.oy < 0      self.oy      -= 32      @new_bitmap.oy -= 32    end    # 更新光标矩形    self.cursor_rect.set(x, y-self.oy, _to_s.size/3*32, 32)endend#==============================================================================# ■ Array#------------------------------------------------------------------------------#  数组类又拿数组开刀...#==============================================================================class Array#--------------------------------------------------------------------------# ● 转换 新 字符串#--------------------------------------------------------------------------def new_to_s    string = ""    for unit in self      string += "[#{unit}]"    end    return stringend=begin#--------------------------------------------------------------------------# ● 自相加#--------------------------------------------------------------------------def self_all_plus(array=self)    plus = 0    for unit in self      if unit.is_a?(Array)      plus += self_all_plus(unit)      else      plus += unit.to_i      end    end    return plusend=endend复制代码
            本帖来自P1论坛作者沙漠点灰,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=174280若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: ISA——支持子选项的选择窗口(理论支持无限层)