注册会员 登录
Project1 返回首页

喵呜喵5的树洞 https://rpg.blue/?291206 [收藏] [复制] [分享] [RSS]

日志

【脚本】事件计时器

热度 15已有 2345 次阅读2015-9-12 01:05 |个人分类:脚本| 计时器, false, 开关

范例工程 http://pan.baidu.com/s/1qWkWV7Y (范例中的脚本为包含BUG的旧版本)

=begin
===============================================================================
  事件计时器 By喵呜喵5
===============================================================================

【说明】

  随着时间的推移自动操作开关、独立开关、变量

  利用本脚本可以实现类似种菜这样的效果


  在事件指令的脚本中,输入以下代码来使用本脚本:

    m5_20151117_set_time(计时器的设置)

  计时器的设置使用如下格式:

    {
      设置的属性1: 属性1的值,
      设置的属性2: 属性2的值,
      设置的属性n: 属性n的值,
    }

    ※ 前后的中括号是必须的,每条属性名后面的英文冒号是必须的
    ※ 冒号和属性的值之间请加上空格,不要忘记每条设置最后的英文逗号
    ※ 为了防止脚本太长被编辑器强制修改,请手动在每条属性后换行

  需要设置的属性如下:

    类型    设置为 '地图' 时,计时器仅在主角处于本地图时才会继续计时
            默认值为 '全局'
            前后需要加上英文引号

    操作    设置计时器时间到以后要执行的指令,可以使用的值为:
            '变量' '开关' '独立开关'
            前后需要加上英文引号

    时间    设置计时器的倒计时时间(帧),
            当时间到了以后,将执行上面设置的操作

    ===========================================================================

    ※ 当操作部分设置为'变量'时:


    变量ID  设置计时器归零后要操作的变量ID

    变量值  设置计时器归零后,对应ID变量的值

    ===========================================================================

    ※ 当操作部分设置为'开关'时:

    开关ID  设置计时器归零后要操作的开关ID

    开关值  设置计时器归零后,对应开关的状态
            true 表示开关开启, false 表示开关关闭
            默认为 true

    ===========================================================================

    ※ 当操作部分设置为'独立开关'时:

    地图ID  设置计时器归零后要操作独立开关的事件所在的地图
            默认为当前地图

    事件ID  设置计时器归零后要操作独立开关的事件的事件ID
            默认为当前事件

    开关ID  设置计时器归零后要操作的独立开关
            可以使用的值分别是:'A' 'B' 'C' 'D'
            前后需要加上英文引号

    开关值  设置计时器归零后,对应独立开关的状态
            true 表示开关开启, false 表示开关关闭
            默认为 true

    ※ 虽然上一版中操作独立开关的设置方式仍然可以使用,但是个人建议尽快更新
    ※ 旧版脚本的操作方式预计将在未来的某个版本中被移除

    ===========================================================================

    指针    设置一个储存当前事件指针的 变量ID 用于结束该计时器
            不需要的话,不去设置即可
            关于结束计时器计时的方法请参考下方的说明


  结束某个计时器的计时:

    设置了指针属性的计时器可以提前结束计时

    例如,将某个计时器的指针属性设置为 1 时

    在计时器的计时过程中,执行指令:

      M5Timer20150824.clear(1)

    该计时器便会被删除

    执行指令:

      M5Timer20150824.start(1)

    该计时器的时间便会立刻归零

    请注意,这里设置的指针 1 表示数据被保存到了 1 号变量中,

    若之后修改了 1 号变量的值,执行结束计时器指令时将会发生错误,其他值亦同

=end
$m5script ||= {};$m5script[:M5Timer20150824] = 20170210
module M5Timer20150824
#==============================================================================
#  设定部分
#==============================================================================

  SWI = 0

  # 对应ID的开关打开时,计时器暂停

  SCENE_LIST = [Scene_Map, Scene_Battle]

  # 设置要让时间流逝的场景
  #
  # 默认的设置里,除了地图场景和战斗场景外,在其他场景中(例如打开菜单时),
  # 计时器会暂停计时

#==============================================================================
#  设定结束
#==============================================================================
class << self
  def update; $game_timer.m5timer20150824.update; end
  def start *args; $game_timer.m5timer20150824.start *args; end
  def clear *args; $game_timer.m5timer20150824.clear *args; end
  def add *args; $game_timer.m5timer20150824.add *args; end
  def refresh_scene; $game_timer.m5timer20150824.refresh_scene; end
end
class Timer
  def collect_event_id(id)
    value = $game_variables[id]
    return [] unless value.is_a? Array
    return [] unless value[0] == :m5_20151117
    ev_id = value[1]
    return [] unless @event_list[ev_id].object_id == value[2]
    [ev_id]
  end
  def start(id)
    operate_event(collect_event_id(id), true, true)
  end
  def clear(id)
    operate_event(collect_event_id(id), false, true)
  end
  def initialize
    @scene = false
    clear_all
  end
  def clear_all
    @map_timeline = []
    @global_timeline = []
    @event_list = []
    @timeline_list = []
  end
  def add_event(value)
    ev_id = @event_list.index(nil) || @event_list.size
    @event_list[ev_id] = value
    return ev_id
  end
  def add_timeline(ev_id, time_id)
    if !time_id
      time_id = @timeline_list.index(nil) || @timeline_list.size
      @timeline_list[time_id] = []
    end
    @timeline_list[time_id] << ev_id
    return time_id
  end
  def add(global, time, event)
    timeline = global ? @global_timeline : @map_timeline[event[:_MAP]]
    timeline ||= []
    ev_id = add_event(event)
    time_id = add_timeline(ev_id, timeline[time])
    event[:_TIME] = timeline[time] = time_id
    if event[:指针]
      $game_variables[event[:指针]] = [:m5_20151117, ev_id, event.object_id]
    end
  end
  def operate_timeline(time_id)
    index_list = @timeline_list[time_id]
    operate_event(index_list, true)
    @timeline_list[time_id] = nil
  end
  def operate_event(index_list, start, update_timeline = false)
    index_list.each do |ev_id|
      next unless @event_list[ev_id]
      if update_timeline
        time_id = @event_list[ev_id][:_TIME]
        @timeline_list[time_id].delete(ev_id)
      end
      start ? start_event(ev_id) : clear_event(ev_id)
    end
  end
  def clear_event(index)
    @event_list[index] = nil
  end
  def refresh_scene
    scene = SceneManager.scene.class
    SCENE_LIST.each {|s| return (@scene = true) if s == scene }
    @scene = false
  end
  def update
    return unless @scene
    return if $game_switches[SWI]
    update_list @map_timeline[$game_map.map_id]
    update_list @global_timeline
  end
  def update_list(list)
    return unless list
    time_id = list.shift
    return unless time_id
    operate_timeline(time_id)
  end
  def start_event(index)
    event = @event_list[index]
    return unless event
    case event[:操作]
    when "变量" then operate_variable(event)
    when "开关" then operate_switches(event)
    when "脚本" then operate_script(event)
    when "独立开关" then operate_self_switches(event)
    end
    $game_variables[event[:指针]] = 0 if event[:指针]
    clear_event(index)
  end
  def operate_variable(event)
    $game_variables[event[:变量ID]] = event[:变量值]
  end
  def operate_switches(event)
    $game_switches[event[:开关ID]] = event[:开关值]
  end
  def operate_self_switches(event)
    key = [event[:地图ID], event[:事件ID], event[:开关ID]]
    $game_self_switches[key] = event[:开关值]
  end
  def operate_script(event)
    eval(event[:代码])
  end
end
end # M5Timer20150824

class Game_Timer
  attr_reader :m5timer20150824
  alias m5_20151117_initialize initialize
  def initialize
    m5_20151117_initialize
    @m5timer20150824 = M5Timer20150824::Timer.new
  end
end
class << Graphics
  alias m5_20150824_update update
  def update; m5_20150824_update; M5Timer20150824.update; end
end
class Game_Interpreter
  def m5_20151117_set_time(param)
    event = {
      :类型 => '全局',    :_MAP => @map_id,
      :地图ID => @map_id, :事件ID => @event_id, :开关值 => true,
    }
    event.merge!(param)
    global = event[:类型] == '全局'
    time = event[:时间] || (raise '未设置计时器时间!')
    event[:操作] || (raise '未设置操作类型!')
    case event[:操作]
    when '变量'
      raise '未设置变量ID!' unless event[:变量ID]
      raise '未设置变量值!' unless event[:变量值]
    when '开关', '独立开关'
      raise '未设置开关ID!' unless event[:开关ID]
    end
    M5Timer20150824.add(global, time, event)
  end
  def m5_20150912_set_time *args
    args = [@map_id, @event_id].concat args if args[0].is_a?(String)
    args.insert(3,true) if args[3].is_a?(Numeric)
    args[5] = "A" unless args.size == 6
    type = args[5] == "A" ? '全局' : '地图'
    event = {
      :地图ID => args[0],  :事件ID => args[1], :类型 => type,
      :操作 => '独立开关', :开关ID => args[2], :开关值 => args[3],
      :时间 => args[4]
    }
    m5_20151117_set_time(event)
  end
end
class Scene_Base
  alias m5_20170210_start start
  def start
    M5Timer20150824.refresh_scene
    m5_20170210_start
  end
end

13

鸡蛋
1

鲜花

刚表态过的朋友 (14 人)

发表评论 评论 (11 个评论)

回复 ninitiange2 2015-10-11 14:34
刚好需要!非常感谢
回复 童话chan 2015-11-16 07:22
太感谢了,正需要这个!!!
回复 duzine 2015-12-4 00:47
新版的似乎衝突的腳本變多了,真可惜
舊版沒出現此問題0.0
回复 喵呜喵5 2015-12-4 07:36
duzine: 新版的似乎衝突的腳本變多了,真可惜
舊版沒出現此問題0.0
你不告诉我错误的具体详情,只说一句 似乎 的话,我也无能为力
回复 duzine 2015-12-4 12:02
undefined method 'update' for nil:Nilclass
大概在 133行,在讀取存檔時會出現這樣的錯誤
舊版沒有,當時要睡之前才發現,所以就只做簡單的回報
具體我也不清楚
回复 喵呜喵5 2015-12-4 13:30
duzine: undefined method 'update' for nil:Nilclass
大概在 133行,在讀取存檔時會出現這樣的錯誤
舊版沒有,當時要睡之前才發現,所以就只做簡單的回報
具體我也不清 ...
重复多遍:插入新脚本后,不要读取旧存档,不要读取旧存档,不要读取旧存档
回复 duzine 2017-2-9 23:42
事件計時器 跟 一些存檔腳本衝突了 網址如下https://github.com/lctseng/RGSS/blob/master/RGSS3/%E6%94%B9%E8%89%AF%E5%AD%98%E6%AA%94%E6%A0%BC.rb
這次的BUG是時隔一年後發現的,觸發方式為存檔後,讀取,再存檔會發生錯誤
比照過一年前的遊戲工程後發現,舊版計時器不會觸發衝突
於是再度前來回報,希望進行更新提高兼容度 (其他存檔類腳本也會觸發類似錯誤
回复 duzine 2017-2-9 23:44
這次不是讀取舊存檔的問題了 (以前新手黑歷史
回复 喵呜喵5 2017-2-10 09:49
duzine: 事件計時器 跟 一些存檔腳本衝突了 網址如下https://github.com/lctseng/RGSS/blob/master/RGSS3/%E6%94%B9%E8%89%AF%E5%AD%98%E6%AA%94%E6%A0%BC.rb
這次的BUG ...
报错说明呢……
回复 喵呜喵5 2017-2-10 10:23
duzine: 事件計時器 跟 一些存檔腳本衝突了 網址如下https://github.com/lctseng/RGSS/blob/master/RGSS3/%E6%94%B9%E8%89%AF%E5%AD%98%E6%AA%94%E6%A0%BC.rb
這次的BUG ...
修正了
回复 duzine 2017-2-10 14:02
太神啦,膜拜一下

facelist doodle 涂鸦笔

您需要登录后才可以评论 登录 | 注册会员

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

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

GMT+8, 2020-7-10 23:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

返回顶部