じ☆ve冰风 发表于 2024-4-20 00:51:41

【相隔1年多的更新][22.1.2015][v0.8】便民任务界面

2015年1月22日正式开坑:下次更新时此脚本将升格为任务系统

@Wait@Cache 防bug=w=

用注释设置使设置更加简单
更新日志:v0.8    1.添加了自动换行功能    2.删除了垂直对齐功能(对已使用的人深感抱歉)    4.更改了文本的解析法    3.描绘内容与刷新同步(可较顺滑的在任务间切换)    4.修正一个没被发现的BUG      v0.7    1.对脚本结构进行优化    2.更改数据结构(也就是说之前的存档再度全死)    3.缩短代码    4.加入自动记录并返回上个界面的功能    5.移除一个没用却一直忘了删掉的功能 =_=||    6.添加垂直对齐功能(很坑,请依情况使用)    7.添加把多行内容显示为一行的功能      v坑爹(超坑爹!失败告终)    1.添加ERB支持(非常坑,已放弃)    2.添加任务系统(已暂停并删除,以后会继续)    3.拥有自己的数据库(很坑,已抛弃)      v0.6    1.增加滚动功能    2.对脚本结构进行优化      v0.5    1.改名为任务界面(总觉得这只是界面不是系统)    2.优化所有正则表达式的匹配模式    4.解决一个大BUG    5.更改数据结构(也就是说之前的存档全死)    6.增加“追加说明”的功能      v0.4    1.优化代码    2.增加“任务更新”的功能      v0.3    1.增加“放弃任务”的功能    2.解决一个未曾被发现的BUG    3.设置简单化    4.美化打勾    5.增加打叉      v0.2    1.加强说明显示效果    2.去掉一些不必要的工作复制代码脚本:
RUBY 代码
#==============================================================================#
#                        便民任务界面 by EngShun                           #
#                                                                              #
#    由于此版本仅做出了一些小优化,                                          #
#    因此设置方法请参考v0.7的范例                                              #
#                                                                              #
#    效果说明:                                                                #
#    支持普通对话框效果                                                      #
#    \a[号码]   :更改左右对齐方式(0,1,2)。                                 #
#    \itm[物品id] :物品数量                                                    #
#    \wpn[武器id] :武器数量                                                    #
#    \amr[防具id] :防具数量                                                    #
#    \eval{脚本}:运行脚本                                                    #
#    \1line{内容} :把多行的内容显示为一行                                    #
#    \bold      :字体加粗,插入多一次关闭                                    #
#    \italic      :字体打斜,插入多一次关闭                                    #
#    \f[字体名称] :更改字体                                                    #
#    \s[号码]   :更改字体大小                                                #
#    \p[名称]   :插入图片                                                    #
#    \icon[名称]:插入图标                                                    #
#                                                                              #
#==============================================================================#

#===============================================================================
# ■ 队伍
#===============================================================================
class Game_Party
Mission = Struct.new(:id, :name, :info, :status)
alias org_init_mission initialize if !defined?(org_init_mission)
#--------------------------------------------------------------------------
# ● 重定义初始化
#--------------------------------------------------------------------------
def initialize
    @mission = {}
    org_init_mission
end
def no_mission?
    return@mission == {}
end
def missions
    if no_mission?
      m = Mission.new(0,"没有任务","\n\n\n\\a\\s你还没有领取任何任务",0)
      return
    end
    return@mission.values.sort_by{|m|m.id}
end
def get_mission(mission,info)
    returnif@mission.has_key?(mission)
    id = missions[-1].id + 1
    @mission = Mission.new(id,mission,info,0)
end
def done_mission(mission)
    @mission.status = 1if@mission.status == 0
end
def delete_mission(mission)
    @mission.delete(mission)
end
def fail_mission(mission)
    @mission.status = 2if@mission.status == 0
end
def resume_mission(mission)
    @mission.status = 0if@mission.status == 2
end
def done_all_mission
    @mission.each{|k,m|m.status = 1}
end
def update_mission(mission,info)
    @mission.info = info
end
def add_mission_info(mission,info)
    @mission.info += "\n" + info
end
def delete_all_mission
    @mission = {}
end
def resume_all_mission
    @mission.each{|k,m|m.status = 0if m.status == 2}
end
end

#===============================================================================
# ■ 任务列表窗口
#===============================================================================
class Window_Mission < Window_Selectable
#--------------------------------------------------------------------------
# ● 初始化对象
#--------------------------------------------------------------------------
def initialize
    super(0, 64, 200, 416)
    self.index = 0
    @mission = $game_party.missions
    @item_max = @mission.size
    ifself.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    self.contents = Bitmap.new(width - 32, @item_max * 32)
    for i in0...@mission.size
      t = @mission.status != 0
      self.contents.font.color = t ? disabled_color : normal_color
      text = @mission.name
      self.contents.draw_text(4, i * 32, 160, 32, text.to_s)
      self.contents.font.color = system_color
      self.contents.draw_text(self.contents.width-32, i * 32, 32, 32, "□",1)unless$game_party.no_mission?
      if@mission.status == 1
      self.contents.font.color = crisis_color
      self.contents.draw_text(self.contents.width-32, i * 32, 32, 32, "√",1)
      elsif@mission.status == 2
      self.contents.font.color = knockout_color
      self.contents.draw_text(self.contents.width-32, i * 32, 32, 32, "×",1)
      end
    end
end
end

#===============================================================================
# ■ 任务详情窗口
#===============================================================================
class Window_MissionInfo < Window_Base
attr_accessor :wait
attr_accessor :scroll_up
#--------------------------------------------------------------------------
# ● 初始化对象
#--------------------------------------------------------------------------
def initialize
    super(200,64,440,416)
    self.contents =Bitmap.new(408, 384)
    @scroll_up = false
    @wait = 90
    @items = []
    @progress = 0
    @draw_y = 0
    @align = 0
    @cache = Bitmap.new(160,160)
    @font = Font.new
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update
    super
    parse_items if@items.size > 0
    returnifself.contents.height0
    self.oy += @scroll_up ? -1 : 1
    self.oy = 0ifself.oy < 0
    self.oy = oy_max ifself.oy > oy_max
    ifself.oy = oy_max
      @scroll_up = true
      @wait = 60
    end
end
#--------------------------------------------------------------------------
# ● 释放
#--------------------------------------------------------------------------
def dispose
    super
    @cache.dispose
end
#--------------------------------------------------------------------------
# ● 滚动最大值
#--------------------------------------------------------------------------
def oy_max
    returnself.contents.height - 384
end
#--------------------------------------------------------------------------
# ● 刷新
#--------------------------------------------------------------------------
def refresh(str)
    str = str.clone
    @scroll_up = false
    @wait = 120
    @draw_y = 0
    @align = 0
    @progress = 0
    @lines = []
    self.oy = 0
    @cache.font = Font.new
    @font = Font.new
    self.contents.dispose
    self.contents = Bitmap.new(408, 384)
    parse_text(str)
    12.times{parse_items}
end
#--------------------------------------------------------------------------
# ● 描绘行
#--------------------------------------------------------------------------
def draw_line(width, height, items)
    bitmap = Bitmap.new(width, height)
    bitmap.font = @font
    x = 0
    for item in items
      if item.is_a?(Color)
      bitmap.font.color = item
      elsif item.is_a?(Integer)
      bitmap.font.size = item
      elsif item.is_a?(Array)
      bitmap.font.name = itemif item.size == 1
      elsif item.is_a?(Bitmap)
      bitmap.blt(x + 2, (height - item.height) / 2,
                   item, Rect.new(0,0,item.width,item.height))
      x += item.width + 4
      elsif item == :bold
      bitmap.font.italic = !bitmap.font.bold
      elsif item == :italic
      bitmap.font.italic = !bitmap.font.italic
      else
      bitmap.draw_text(x,0,width,height,item)
      x += bitmap.text_size(item).width
      end
    end
    return bitmap
end
#--------------------------------------------------------------------------
# ● 解析文本
#--------------------------------------------------------------------------
def parse_text(str)
    begin
      last_text = str.clone
      str.gsub!(/\\v\[(\d+)\]/i){$game_variables[$1.to_i]}
      str.gsub!(/\\g/i){$game_party.gold.to_s}
      str.gsub!(/\\itm\[(\d+)\]/i){$game_party.item_number($1.to_i)}
      str.gsub!(/\\wpn\[(\d+)\]/i){$game_party.weapon_number($1.to_i)}
      str.gsub!(/\\amr\[(\d+)\]/i){$game_party.armor_number($1.to_i)}
      str.gsub!(/\\1line{(.+?)}/im){ $1.delete("\n")}
      str.gsub!(/\\eval{(.+?)}/im){eval($1)}
    enduntil str == last_text
    str.gsub!(/\\n\[(\d+)\]/i)do
      $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
    end
    str.gsub!(/\n/){"\000\002n\000"}
    str.gsub!(/\\\\/){"\001"}
    str.gsub!(/\\a\[()\]/i){"\000\0027#{$1}"}
    str.gsub!(/\\c\[(\d+)\]/i){"\000\0020#{$1}\000"}
    str.gsub!(/\\bold/i){"\000\0021\000"}
    str.gsub!(/\\italic/i){"\000\0022\000"}
    str.gsub!(/\\f\[(\w+)\]/i){"\000\0023#{$1}\000"}
    str.gsub!(/\\s\[(\d+)\]/i){"\000\0024#{$1}\000"}
    str.gsub!(/\\p\[(.+?)\]/i){"\000\0025#{$1}\000"}
    str.gsub!(/\\icon\[(.+?)\]/i){"\000\0026#{$1}\000"}
    str.gsub!(/\001/){"\\"}
    @items = str.split("\000")
    @items.delete("")
end
#--------------------------------------------------------------------------
# ● 深度解析
#--------------------------------------------------------------------------
def parse_items
    returnunless@items.size > 0
    bitmap = @cache
    width, height, items = 1, 32, []
    while item = @items.delete_at(0)
      if item[/^\002()(.*)/]
      case(a = $1)
      when'7'
          @align = $2.to_i
      when'0'
          color = $2.to_i
          bitmap.font.color = if color >= 0and color408
            item.dispose
            items.unshift("[图片太大无法显示]")
            next
          elsif width + item.width > 408
            @items.unshift(item)
            break
          end
          items.push(item)
          width += item.width + 4
          height = item.height + 4if item.height + 4 > height
      when'n'
          break
      end
      else
      str = ""
      size = Rect.new(0, 0, 0, 0)
      while s = item.slice!(/./)
          size = bitmap.text_size(str + s)
          if width + size.width > 408
            item.insert(0, s)
            break
          else
            str += s
          end
      end
      if items[-1].is_a?(String)
          items[-1] += str
      else
          items.push(str)
      end
      width += size.width
      height = size.height + 4if size.height + 4 > height
      if item != ""
          @items.unshift(item)
          break
      end
      end
    end
    b = draw_line(width, height, items)
    if@draw_y + b.height > 384
      c = self.contents
      self.contents = Bitmap.new(408, @draw_y + b.height)
      self.contents.blt(0, 0, c, Rect.new(0,0,c.width, c.height))
      c.dispose
    end
    x = 0
    x = 204 - (b.width / 2)if@align == 1
    x = 408 - b.widthif@align == 2
    self.contents.blt(x, @draw_y, b, Rect.new(0,0,b.width, b.height))
    @draw_y += b.height
end
end

#===============================================================================
# ■ 任务界面
#===============================================================================
class Scene_Mission
#--------------------------------------------------------------------------
# ● 初始化
#--------------------------------------------------------------------------
def initialize
    @last_scene = $scene
end
#--------------------------------------------------------------------------
# ● 主处理
#--------------------------------------------------------------------------
def main
    @mission = $game_party.missions
    @window1 = Window_Base.new(0,0,200,64)
    @window1.contents = Bitmap.new(168,32)
    @window1.contents.draw_text(0,0,168,32,"任务",1)
    @window2 = Window_Base.new(200,0,440,64)
    @window2.contents = Bitmap.new(408,32)
    @window2.contents.draw_text(0,0,408,32,"任务说明",1)
    @mission_window = Window_Mission.new
    @mission_window.index = @mission.size - 1
    @index = @mission_window.index
    @info_window = Window_MissionInfo.new
    @info_window.refresh(@mission[@index].info)
    Graphics.transition
    loopdo
      Graphics.update
      Input.update
      update
      if$scene != self
      break
      end
    end
    Graphics.freeze
    @window1.dispose
    @window2.dispose
    @mission_window.dispose
    @info_window.dispose
end
#--------------------------------------------------------------------------
# ● 刷新画面
#--------------------------------------------------------------------------
def update
    @mission_window.update
    @info_window.update
    if@index != @mission_window.index
      @index = @mission_window.index
      @info_window.refresh(@mission[@index].info)
    end
    return update_mission if@mission_window.active
    update_info
end
#--------------------------------------------------------------------------
# ● 刷新任务
#--------------------------------------------------------------------------
def update_mission
    if Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @mission_window.active = false
      @info_window.oy = 0
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = @last_scene
      return
    end
end
#--------------------------------------------------------------------------
# ● 刷新人物详情
#--------------------------------------------------------------------------
def update_info
    @info_window.wait = 90
    if Input.press?(Input::UP)
      @info_window.oy -= 3
      @info_window.oy = 0if@info_window.oy < 0
    elsif Input.press?(Input::DOWN)
      @info_window.oy += 3
      @info_window.oy = @info_window.oy_maxif@info_window.oy > @info_window.oy_max
    elsif Input.repeat?(Input::L)
      $game_system.se_play($data_system.cursor_se)
      @mission_window.index -= 1
      @mission_window.index = $game_party.missions.size - 1if@mission_window.index < 0
    elsif Input.repeat?(Input::R)
      $game_system.se_play($data_system.cursor_se)
      @mission_window.index += 1
      @mission_window.index = 0if@mission_window.index >= $game_party.missions.size
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @mission_window.active = true
      @info_window.scroll_up = false
      @info_window.oy = 0
    end
end
end

#===============================================================================
# ■ 事件处理器
#===============================================================================
class Interpreter
alias orig_ec_mission execute_command if !defined?(orig_ec_mission)
#--------------------------------------------------------------------------
# ● 重定义执行事件命令
#--------------------------------------------------------------------------
def execute_command
    if@index >= @list.size - 1
      command_end
      returntrue
    end
    @parameters = @list[@index].parameters
    return command_108 if@list[@index].code == 108
    return orig_ec_mission
end
#--------------------------------------------------------------------------
# ● 注释
#--------------------------------------------------------------------------
def command_108
    case@list[@index].parameters
    when(/^删除任务\[(\w+)\]$/)
      $game_party.delete_mission($1)
      returntrue
    when(/^完成任务\[(\w+)\]$/)
      $game_party.done_mission($1)
      returntrue
    when"删除所有任务"
      $game_party.delete_all_mission
      returntrue
    when"完成所有任务"
      $game_party.done_all_mission
      returntrue
    when(/^放弃任务\[(\w+)\]$/)
      $game_party.fail_mission($1)
      returntrue
    when(/^恢复任务\[(\w+)\]$/)
      $game_party.resume_mission($1)
      returntrue
    when"恢复所有任务"
      $game_party.resume_all_mission
      returntrue
    end
    text = @list[@index].parameters
    loopdo
      if@list[@index+1].code == 108or@list[@index+1].code == 408
      text += "\n" + @list[@index+1].parameters
      else
      break
      end
      @index += 1
    end
    split = text.split("\n")
    if(split == "任务设置"orsplit == "任务更新"orsplit == "追加说明")andsplit.size >= 3
      info , name = split , split
      ifsplit.size >= 4
      for i in3...split.size
          info += "\n" + split
      end
      end
      $game_party.get_mission(name,info)ifsplit == "任务设置"
      $game_party.update_mission(name,info)ifsplit == "任务更新"
      $game_party.add_mission_info(name,info)ifsplit == "追加说明"
    end
    returntrue
end
end

截图:


下载:
v0.8并没有在功能上做出改动,因此不提供范例,
需要的请下载v0.7范例。
随工程附送VX→XP窗口皮肤一张

旧版本:





         
             本帖来自P1论坛作者英顺的马甲,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=167490若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: 【相隔1年多的更新][22.1.2015][v0.8】便民任务界面