查看: 31490|回复: 49

[已发主站] VA任务系统

[复制链接]
梦石
0
星屑
60
在线时间
79 小时
注册时间
2007-2-11
回帖
135
发表于 2012-5-22 16:34:42 | 显示全部楼层 |阅读模式

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

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

×
好久没来这里了。。
这几天突发奇想做游戏,然后昨天就下载了VA。想给游戏里加个查看任务的功能,然后看到了这个帖子http://rpg.blue/thread-216707-1-1.html
恩。。因为不是很喜欢这个布局所以想改动改动,结果发现自己改不动- -!
于是就有了以下代码。。(基本上是复制粘贴系统本身查看物品的代码。。汗死。。我自己觉得相当山寨啊~但是难得自己折腾出来个东西,难得想发帖,于是就放上来了。。)

[pre lang="Ruby" line="1"]#encoding:utf-8

#==============================================================================
# ■ Task
#------------------------------------------------------------------------------
#  任务类。本类在 Game_Task 类的内部使用。
#   任务属性:名称,内容,是否是主线任务,是否有父任务
#==============================================================================

class Task
  attr_reader :index
  attr_reader :name
  attr_reader :description
  attr_reader :type
  attr_reader :father_task
  attr_reader :finished
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize(index, name, description, type = true, father_task = -1)
    @type = type
    @name = name
    @description = description
    @father_task = father_task
    @index = index
    @finished = false
  end
  #--------------------------------------------------------------------------
  # ● 是否是主线任务
  #--------------------------------------------------------------------------
  def key_task?
    @type
  end
  #--------------------------------------------------------------------------
  # ● 是否是子任务
  #--------------------------------------------------------------------------
  def has_father_task?
    @father_task > -1
  end
  #--------------------------------------------------------------------------
  # ● 完成任务
  #--------------------------------------------------------------------------
  def finish
    @finished = true
  end
   
end

#==============================================================================
# ■ Game_Party
#==============================================================================

class Game_Party < Game_Unit
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  alias old_init initialize
  def initialize
    old_init
    @tasks = {}
    @sub_tasks= {}
    #定义了一个任务列表,提前把所有的任务都写进去了
    @task_list=TaskList.new
    @sub = false
  end
  #--------------------------------------------------------------------------
  # ● 是否存在子任务
  #--------------------------------------------------------------------------
  def is_sub
    @sub
  end
  #--------------------------------------------------------------------------
  # ● 启用子任务
  #--------------------------------------------------------------------------
  def set_sub
    @sub = true
  end
  #--------------------------------------------------------------------------
  # ● 添加新的任务
  #--------------------------------------------------------------------------
  def new_task(i, name, desc, type, father_task = -1)
    if !is_sub
      @tasks = tmp if !have_task?(i)
      return
    end
    tmp = Task.new(i, name, desc, type, father_task)
    if father_task < 0
      @tasks = tmp if !have_task?(i)
    else
      @sub_tasks = tmp if father_task?(father_task) && !sub_task?(i)
    end   
  end
  #--------------------------------------------------------------------------
  # ● 从已定义好的任务列表中添加新的任务
  #--------------------------------------------------------------------------
  def set_task(index)
    temp = @task_list.get_task(index)
    if !is_sub
      @tasks[index] = temp if !have_task?(index)
      return
    end
    if temp.has_father_task?
      @sub_tasks[index] = temp if father_task?(temp.father_task) && !sub_task?(index)
    else
      @tasks[index] = temp if !have_task?(index)
    end
  end
  #--------------------------------------------------------------------------
  # ● 查询任务是否存在
  #--------------------------------------------------------------------------
  def have_task?(i)
    return father_task?(i) || sub_task?(i)
  end
  #--------------------------------------------------------------------------
  # ● 查询父任务是否存在
  #--------------------------------------------------------------------------
  def father_task?(i)
    @tasks != nil
  end
  #--------------------------------------------------------------------------
  # ● 查询子任务是否存在
  #--------------------------------------------------------------------------
  def sub_task?(i)
    @sub_tasks != nil
  end
  #--------------------------------------------------------------------------
  # ● 完成已有的任务,如果该任务有没有完成的子任务,则不能完成
  #--------------------------------------------------------------------------
  def finish_task(i)
    @tasks.finish if father_task?(i) && sub_tasks_finished?(i)
    @sub_tasks.finish if sub_task?(i)
  end
  #--------------------------------------------------------------------------
  # ● 查询父任务序号为i的子任务,返回一个数组
  #--------------------------------------------------------------------------
  def get_sub_tasks(i)
    return [] if !is_sub
    tmp = []
    for j in @sub_tasks.values
      next if j.father_task != i
      tmp.push(j)
    end
    return tmp
  end
  #--------------------------------------------------------------------------
  # ● 查询父任务序号为i的子任务是否都已完成
  #--------------------------------------------------------------------------
  def sub_tasks_finished?(i)
    return true if !is_sub
    for j in @sub_tasks.values
      next if j.father_task != i
      return false if !j.finished
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ● 获取任务类型为cat的任务集合
  #--------------------------------------------------------------------------
  def all_tasks(cat)
    n = []
    m = []
    for i in @tasks.values
      next if i.key_task? != cat
      tmp = get_sub_tasks(i.index)
      if i.finished
        n.push(i)
        n += tmp
      else
        m.push(i)
        m += tmp
      end
    end
    return m + n
  end
  
end

#==============================================================================
# ■ Window_TaskList
#------------------------------------------------------------------------------
#  任务画面中,显示已获得任务的窗口。
#==============================================================================

class Window_TaskList < Window_Selectable
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize(x, y, width, height)
    super
    @category = :none
    @data = []
    @sub_task = false
  end
  #--------------------------------------------------------------------------
  # ● 设置是否有子任务
  #--------------------------------------------------------------------------
  def has_sub_task
    @sub_task = true
  end
  #--------------------------------------------------------------------------
  # ● 设置分类
  #--------------------------------------------------------------------------
  def category=(category)
    return if @category == category
    @category = category
    if category == :true
      refresh(true)
    else
      refresh(false)
    end
    self.oy = 0
  end
  #--------------------------------------------------------------------------
  # ● 获取列数
  #--------------------------------------------------------------------------
  def col_max
    if @sub_task
      return 1
    else
      return 2
    end
  end
  #--------------------------------------------------------------------------
  # ● 获取项目数
  #--------------------------------------------------------------------------
  def item_max
    @data ? @data.size : 1
  end
  #--------------------------------------------------------------------------
  # ● 获取任务
  #--------------------------------------------------------------------------
  def item
    @data && index >= 0 ? @data[index] : nil
  end
  #--------------------------------------------------------------------------
  # ● 获取选择任务的有效状态
  #--------------------------------------------------------------------------
  def current_item_enabled?
    enable?(@data[index])
  end
  #--------------------------------------------------------------------------
  # ● 查询此任务是否完成
  #--------------------------------------------------------------------------
  def enable?(item)
    !item.finished
  end
  #--------------------------------------------------------------------------
  # ● 生成任务列表
  #--------------------------------------------------------------------------
  def make_item_list(type)
    @data = $game_party.all_tasks(type)
  end
  #--------------------------------------------------------------------------
  # ● 返回上一个选择的位置
  #--------------------------------------------------------------------------
  def select_last
    select(0)
  end
  #--------------------------------------------------------------------------
  # ● 绘制项目
  #--------------------------------------------------------------------------
  def draw_item(index)
    item = @data[index]
    if item
      rect = item_rect(index)
      rect.width -= 4
      draw_item_name(item, rect.x, rect.y, enable?(item))
    end
  end
  #--------------------------------------------------------------------------
  # ● 绘制名称
  #     enabled : 有效的标志。false 的时候使用半透明效果绘制
  #--------------------------------------------------------------------------
  def draw_item_name(item, x, y, enabled = true, width = 172)
    return unless item
    text = item.name
    text = "    " + text if @sub_task && item.has_father_task?
    text += "(已完成)" if item.finished
    change_color(normal_color, enabled)
    draw_text(x, y, width, line_height, text)
  end
  #--------------------------------------------------------------------------
  # ● 更新帮助内容
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_item(item)
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def refresh(type)
    make_item_list(type)
    create_contents
    draw_all_items
  end
end

#==============================================================================
# ■ Window_TaskCategory
#------------------------------------------------------------------------------
#  任务画面中,显示任务列表的窗口。
#==============================================================================

class Window_TaskCategory < Window_HorzCommand
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_reader   :item_window
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0)
  end
  #--------------------------------------------------------------------------
  # ● 获取窗口的宽度
  #--------------------------------------------------------------------------
  def window_width
    Graphics.width
  end
  #--------------------------------------------------------------------------
  # ● 获取列数
  #--------------------------------------------------------------------------
  def col_max
    return 2
  end
  #--------------------------------------------------------------------------
  # ● 更新画面
  #--------------------------------------------------------------------------
  def update
    super
    @item_window.category = current_symbol if @item_window
  end
  #--------------------------------------------------------------------------
  # ● 生成指令列表
  #--------------------------------------------------------------------------
  def make_command_list
    add_command("主线任务",   :true)
    add_command("支线任务",   :false)
  end
  #--------------------------------------------------------------------------
  # ● 设置任务窗口
  #--------------------------------------------------------------------------
  def item_window=(item_window)
    @item_window = item_window
    update
  end
end

#==============================================================================
# ■ Scene_Task
#------------------------------------------------------------------------------
#  任务画面
#==============================================================================

class Scene_Task < Scene_ItemBase
  #--------------------------------------------------------------------------
  # ● 开始处理
  #--------------------------------------------------------------------------
  def start
    super
    create_help_window
    create_category_window
    create_task_window
  end
  #--------------------------------------------------------------------------
  # ● 生成分类窗口
  #--------------------------------------------------------------------------
  def create_category_window
    @category_window = Window_TaskCategory.new
    @category_window.viewport = @viewport
    @category_window.help_window = @help_window
    @category_window.y = @help_window.height
    @category_window.set_handler(:ok,     method(:on_category_ok))
    @category_window.set_handler(:cancel, method(:return_scene))
  end
  #--------------------------------------------------------------------------
  # ● 生成任务窗口
  #--------------------------------------------------------------------------
  def create_task_window
    wy = @category_window.y + @category_window.height
    wh = Graphics.height - wy
    @item_window = Window_TaskList.new(0, wy, Graphics.width, wh)
    #如果允许子任务则显示子任务
    @item_window.has_sub_task if $game_party.is_sub
    @item_window.viewport = @viewport
    @item_window.help_window = @help_window
    @item_window.set_handler(:cancel, method(:on_item_cancel))
    @category_window.item_window = @item_window
  end
  #--------------------------------------------------------------------------
  # ● 分类“确定”
  #--------------------------------------------------------------------------
  def on_category_ok
    @item_window.activate
    @item_window.select_last
  end
  #--------------------------------------------------------------------------
  # ● 任务“取消”
  #--------------------------------------------------------------------------
  def on_item_cancel
    @item_window.unselect
    @category_window.activate
  end
end
#==============================================================================
# ■ TaskList
#------------------------------------------------------------------------------
#  
#==============================================================================
class TaskList
  def initialize
    #允许子任务
    @list = []
    @list.push(Task.new(0, "任务0", "任务描述0任务描述0任务描述0任务描述0任务"))
    @list.push(Task.new(1, "任务一", "任务描述1"))
    @list.push(Task.new(2, "任务2", "任务描述2",false))
    @list.push(Task.new(3, "任务3", "任务描述3", true, 1))
    @list.push(Task.new(4, "任务4", "任务描述4", true, 1))
    @list.push(Task.new(5, "任务5", "任务描述5", false, 2))
    @list.push(Task.new(6, "任务6", "任务描述6", false))
    @list.push(Task.new(7, "任务7", "任务描述7", true, 1))
  end
  def get_task(index)
    @list[index]
  end
end[/pre]
上图

允许使用子任务

允许使用子任务

不使用子任务

不使用子任务

有任务完成了

有任务完成了


恩,以下是对脚本的说明。。
我把任务分为主线任务和支线任务,另外一个父任务可以有若干个子任务

打开任务界面:SceneManager.call(Scene_Task)

添加任务
有两种方式。。
1 $game_party.new_task(任务序号, 任务名称, 任务描述, 任务类型, 父任务序号)
如果任务类型为true,则为主线任务,否则为支线任务,默认是true
如果父任务序号为-1,则这个任务没有父任务,他自己就是一个顶级的父任务,可以拥有子任务了。如果父任务序号为已存在的父任务,则可以顺利生成一个子任务,否则不能生成任务
(说得这么好听究竟能不能做到啊- -!我对自己表示怀疑)

2 你看我在代码末尾絮絮叨叨的加了一个 class TaskList,那是因为我觉得一个一个往事件里加任务好累啊- -!所以在代码里都写好了,到时候要用哪个直接序号搞定。。
所以第二种添加方式是$game_party.set_task(该任务在TaskList里的序号)
当然这个任务在TaskList里的序号和他本身的那个序号是一样的了,如果你要写成不一样的,应该是会出问题。。

完成任务
$game_party.finish_task(任务序号)
好吧,这个跟我前面说的那个帖子是一样的。。我深深的觉得自己山寨,向被我山寨的LZ致以崇高的敬意

子任务系统
系统默认是不使用子任务的,这个时候任务列表里面显示任务的时候会有两列。
如果想要使用子任务的话,需要调用$game_party.set_sub
然后任务列表里就只显示一列了(- -!如果显示两列会灰常混乱),然后子任务会在他的父任务后面缩进显示
该系统只支持一级子任务。。

当任务完成后,会在列表里显示“(已完成)”字样,并且任务名称变灰色。已完成的任务一般是显示在未完成任务的后面的(貌似只考虑了父任务的顺序,没有考虑子任务的顺序。囧)。
如果一个父任务他的子任务没有全部完成,那么他也不可能被完成,调用了完成任务的方法也是徒劳啊~

评分

参与人数 2星屑 +200 赞 +6 收起 理由
Shy07 + 6 主站收录
忧雪の伤 + 200 好简陋

查看全部评分

萌萌的小笼包 <

梦石
0
星屑
50
在线时间
193 小时
注册时间
2012-4-30
回帖
622
发表于 2012-5-22 18:00:56 | 显示全部楼层
好东西,虽然不是原创吧!不过分享东西也是不错的!下来用用好了!

点评

我擦,这都多少年前的帖子了还扣分,闲着啊  发表于 2012-7-17 15:56
你能用到就好啦~如果发现Bug要告诉我哦~  发表于 2012-5-22 22:46

评分

参与人数 1星屑 -40 收起 理由
忧雪の伤 -40 抬头

查看全部评分

回复

使用道具 举报

梦石
0
星屑
50
在线时间
33 小时
注册时间
2012-4-13
回帖
14
发表于 2012-5-22 22:26:41 | 显示全部楼层
哈,楼主作出了我刚改到一半的东西,顺便帮楼主补充一下。
Window_MenuCommand  找到下面这几行,加上红色这行(52行左右)

  # ● 向指令列表添加主要的指令
  #--------------------------------------------------------------------------
  def add_main_commands
    add_command(Vocab::item,   :item,   main_commands_enabled)
    add_command(Vocab::skill,  :skill,  main_commands_enabled)
    add_command(Vocab::equip,  :equip,  main_commands_enabled)
    add_command(Vocab::status, :status, main_commands_enabled)
    add_command("任务",        :task,   main_commands_enabled)

Scene_Menu  找到下面这几行,加上红色这几行(62~67行左右)
#--------------------------------------------------------------------------
  # ● 指令“技能”“装备”“状态”
  #--------------------------------------------------------------------------
  def command_personal
    @status_window.select_last
    @status_window.activate
    @status_window.set_handler(:ok,     method(:on_personal_ok))
    @status_window.set_handler(:cancel, method(:on_personal_cancel))
  end
  #--------------------------------------------------------------------------
  # ● 指令“任务”
  #--------------------------------------------------------------------------
  def command_task
    SceneManager.call(Scene_Task)
  end

点评

这还不完全,应该在Scene_Menu“生成指令窗口”中加入 @command_window.set_handler(:task, method(:command_task))一行,否则就召唤不了任务界面。  发表于 2017-1-25 19:00
按照你说的更改了,但是为什么菜单里只可以看见任务就是召唤不了任务界面  发表于 2012-6-12 09:26
恩。。这个添加到菜单的东西,我写了,但是没有发上来- -!谢谢啦~  发表于 2012-5-22 22:44

评分

参与人数 1赞 +1 收起 理由
ConsoleWrite + 1 你说这不对啊,按照你说的做了,打菜单栏就.

查看全部评分

回复

使用道具 举报

梦石
0
星屑
50
在线时间
174 小时
注册时间
2012-3-17
回帖
186
发表于 2012-5-22 22:56:59 | 显示全部楼层
话说改版后似乎更加怪异的说~
任务描述跑上面的小地方去了==i
感觉各种的不协调。

不过,分开主线和支线的改进方便了,值得鼓励!
窗体布局完善一下就更好了!
回复

使用道具 举报

梦石
0
星屑
50
在线时间
59 小时
注册时间
2012-3-4
回帖
64
发表于 2012-6-10 20:39:51 | 显示全部楼层
。。。。。本人很笨,复制不起。。。。。
回复

使用道具 举报

梦石
0
星屑
60
在线时间
79 小时
注册时间
2007-2-11
回帖
135
 楼主| 发表于 2012-6-11 11:35:28 | 显示全部楼层
562305484 发表于 2012-6-10 20:39
。。。。。本人很笨,复制不起。。。。。

你用的虾米浏览器啊。。Google chrome用得没问题。。
回复

使用道具 举报

梦石
0
星屑
75
在线时间
74 小时
注册时间
2010-5-14
回帖
16
发表于 2012-6-12 09:16:45 | 显示全部楼层
接任务后召唤任务界面出问题了



‘‘──tankonsai于2012-6-12 09:22补充以下内容:

7楼的问题解决了
原来在代码里编写任务时任务序号必须要按顺序才可以,否则会报错
’’
问题.jpg

点评

是的。。要按序号。。解决了就好  发表于 2012-6-12 10:58
回复

使用道具 举报

梦石
0
星屑
50
在线时间
59 小时
注册时间
2012-3-4
回帖
64
发表于 2012-6-13 22:04:30 | 显示全部楼层
asd11000 发表于 2012-6-11 11:35
你用的虾米浏览器啊。。Google chrome用得没问题。。

其他发的代码都有复制代码按键,要不大哥给小弟个范例也可以,多少经验都可以啊谢谢了

点评

对了。。LZ是个妹子  发表于 2012-6-14 10:38
回复

使用道具 举报

梦石
0
星屑
60
在线时间
79 小时
注册时间
2007-2-11
回帖
135
 楼主| 发表于 2012-6-14 10:38:23 | 显示全部楼层
562305484 发表于 2012-6-13 22:04
其他发的代码都有复制代码按键,要不大哥给小弟个范例也可以,多少经验都可以啊谢谢了 ...

下载文件回复到你那个提问区的帖子了。
有啥问题直接问我就成。
回复

使用道具 举报

梦石
0
星屑
50
在线时间
60 小时
注册时间
2011-12-3
回帖
40
发表于 2012-6-15 08:50:13 | 显示全部楼层
我要早点看到这贴。。我做那游戏的任务系统就不用物品触发了。。。因为不会脚本,我只能是每接一个任务,给一个任务物品,然后用任务物品去触发某些事件,任务说明只能局限于物品说明那短短两行。。。游戏做了大半了。。。改起来都没新信心了。。

点评

555.....我也是这样做的  发表于 2012-8-7 10:40
回复

使用道具 举报

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

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部