设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 15499|回复: 37
打印 上一主题 下一主题

[原创发布] 【原创】【插件】RPG游戏中的QTE Ver 1.1

[复制链接]

Lv4.逐梦者 (版主)

梦石
0
星屑
9497
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

跳转到指定楼层
1
发表于 2014-6-16 11:45:57 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 RyanBern 于 2014-12-12 17:33 编辑

废话不多说,直接上脚本和图示说明。由于自己最近玩了很多脑残的动作游戏,被里面的QTE弄疯了,因此自制了一个朴素版的插件玩玩。
说明贴在脚本最前头了,如果有BUG什么的通知我下,懂脚本的也可以自行更正-_-||
RUBY 代码复制
  1. #=============================================================================
  2. # 紧急操作事件(Quick Time Event)小插件 Ver 1.1
  3. #-----------------------------------------------------------------------------
  4. # 作者:RyanBern
  5. #=============================================================================
  6.  
  7. #=============================================================================
  8. # 功能说明:
  9. #-----------------------------------------------------------------------------
  10. # 可以实现在RMXP游戏进行中的QTE,虽然把QTE放在RPG游戏中感觉很奇怪,没什么用。
  11. # 但是为了好玩,就做了一个这个。如果有全键盘脚本的话,对此插件稍微加点
  12. # 改动就可以实现更多按键的QTE。不过本脚本针对的是原装脚本的输入系统而编写的。
  13. # 插件较朴素,只是实现了一些简单的功能,有时间我会陆续添加。
  14. #-----------------------------------------------------------------------------
  15. # 这里包含两种QTE的模式:单按键瞬时紧急事件(QTE_Single)和按键组蓄力紧急事件
  16. # (QTE_Combination)。前者是在适当时间点按下规定的按键即可完成一次QTE,又分为
  17. # 有时限和无时限两种;后者是在一定时间内依照次序不断输入按键组,达到规定次数就
  18. # 可以完成QTE,也分为有时限和无时限两种。
  19. #-----------------------------------------------------------------------------
  20. # 有关脚本的兼容性,本脚本在新工程的环境下编写,新增了若干模块,对原有的脚本
  21. # 改动极小,经过简单整合就可以实现兼容。但是对于RTAB战斗系统的兼容性未经测试
  22. #=============================================================================
  23.  
  24. #=============================================================================
  25. # 使用说明:
  26. #-----------------------------------------------------------------------------
  27. # 我已经在地图场景(Scene_Map)和战斗场景(Scene_Battle)添加了这两种QTE的插件
  28. # 不用的时候它们隐藏在场景中,如果使用的时候,可以通过事件“脚本”命令进行手动
  29. # 激活。
  30. #-----------------------------------------------------------------------------
  31. # 单按键瞬时紧急事件(QTE_Single)的启动方法
  32. # qte = $scene.get_QTE_single    # 取得当前场景的QTE_Single插件
  33. # qte.time_limit = XX            # 设置时限,单位是帧,如果不想设置时间限制,请设置为0
  34. # qte.keys = [XX,XX]            # 设置按键,可以设置多个,玩家必须按照次序全部按对才算QTE成功
  35. # qte.success_field = [[XX,XX], [XX,XX]]
  36. #                                # 设置有效按键区域,最大范围是[0,100]
  37. #                                  例如设置[50,60]表示只有在指针经过这个区域按下
  38. #                                  指定按键才算QTE成功,每个按键都必须设置,否则会报错。
  39. # qte.non_mistake_mode = true/false
  40. #                                # 设置是否允许按错,这里按错的定义是按错按键或者按对了
  41. #                                  但是没有在规定区域上。如果设置为true则按错一次QTE就会失败。
  42. # qte.start                      # 激活QTE插件
  43. # QTE结束后,可以使用
  44. # $scene.get_QTE_single.result   # 显示最近一次QTE结果,成功为true,失败为false
  45. #-----------------------------------------------------------------------------
  46. # 按键组蓄力紧急事件(QTE_Combination)的启动方法
  47. # qte = $scene.get_QTE_com       # 取得当前场景的QTE_Combination插件
  48. # qte.time_limit = XX            # 设置时限,单位是帧,如果不想设置时间限制,请设置为0
  49. # qte.key_set = [XX,XX,…,XX]    # 设置按键组,例如[Input::LEFT,Input::Right]
  50. #                                  表示需要按照顺序按下这一组键才能蓄力,循环操作
  51. # qte.power_need = XX            # 设置QTE成功需要的蓄力能量
  52. # qte.power_increment = XX       # 设置成功按键一次后,增加的能量
  53. # qte.power_decrement = XX       # 设置自动随时间减少的能量,单位是 能量/帧,数值不宜过
  54. #                                  大,否则会很变态。
  55. # qte.start                      # 激活QTE插件
  56. # QTE结束后,可以使用
  57. # $scene.get_QTE_single.result   # 显示最近一次QTE结果,成功为true,失败为false
  58. #-----------------------------------------------------------------------------
  59. # 注意事项(重要):
  60. #-----------------------------------------------------------------------------
  61. # 1.使用事件“脚本”指令设置并开启QTE插件后,需要设置“等待 3 帧”,然后再使用
  62. #   事件“条件分歧——脚本——$scene.get_QTE_Xx.result”进行分歧,否则事件解释
  63. #   器会提前进行判断。
  64. # 2.如果QTE组件被激活,那么场景的update会优先刷新QTE组件,而其它模块的刷新会暂
  65. #   时停止。QTE完成后,再进行正常刷新。
  66. # 3.不可以同时激活两种QTE插件。
  67. # 4.禁止在非地图场景和战斗场景里面获取相应的QTE组件。
  68. # 5.如果对技能里面使用QTE,建议把技能的效果全都放到公共事件中,效果范围设置
  69. #   为[无],之后关联公共事件,先开启QTE,然后“等待 3 帧”,再对QTE结果做伤
  70. #   害处理。
  71. #=============================================================================
  72.  
  73. #=============================================================================
  74. # 更新记录
  75. #-----------------------------------------------------------------------------
  76. # Ver 1.1 : 修改 QTE_Single,增加功能可以连续点击一组按键,同时QTE_Single具备
  77. #           了按错即QTE失败的功能。原QTE_Combination功能不变。
  78. #           注:QTE_Single中的字段做了修改,和1.0不兼容。
  79. #=============================================================================
  80.  
  81. #=============================================================================
  82. # 素材/基础设定
  83. #=============================================================================
  84. module QTE
  85.   # QTE 组件游标图,大小 24*24,放在Graphis/Icons下
  86.   ICON_NAME = "047-Skill04.png"
  87.   # QTE 成功播放 SE
  88.   SUCCEEDED_SE = "Audio/SE/002-System02"
  89.   # QTE 失败播放 SE
  90.   FAILED_SE = "Audio/SE/004-System04"
  91.   # 可用 QTE 按键集合及用语设定
  92.   ALL_KEYS = {
  93.               Input::A => "Z",  Input::B => "X", Input::C => "Space",
  94.               Input::UP => "↑", Input::DOWN => "↓", Input::LEFT => "←",
  95.               Input::RIGHT => "→", Input::SHIFT => "Shift",
  96.               Input::CTRL => "Ctrl", Input::ALT => "ALT"
  97.               }
  98. end
  99.  
  100. module Input
  101.   def self.key_trigger?
  102.     return QTE::ALL_KEYS.keys.any?{|key| self.trigger?(key)}
  103.   end
  104. end
  105.  
  106. class Window_QTE_Base < Window_Base
  107.   attr_accessor :time_limit
  108.   attr_reader   :activated
  109.   attr_reader   :result
  110.   def initialize
  111.     super(-160, 320, 160, 96)
  112.     self.z = 999
  113.     self.visible = false
  114.     @activated = false
  115.     @result = false
  116.     @state = 0
  117.     @time_limit = 0
  118.     @time_count = 0
  119.     @arrow_sprite = Sprite.new
  120.     @arrow_sprite.bitmap =  Bitmap.new(24, 24)
  121.     if QTE::ICON_NAME != ""
  122.       @arrow_sprite.bitmap = RPG::Cache.icon(QTE::ICON_NAME)
  123.     end
  124.     @x_increment = 16
  125.     @y_increment = 56
  126.     @arrow_sprite.x = self.x + @x_increment
  127.     @arrow_sprite.y = self.y + @y_increment
  128.     @arrow_sprite.z = self.z + 10
  129.     @arrow_sprite.ox = @arrow_sprite.bitmap.width / 2
  130.     @arrow_sprite.oy = @arrow_sprite.bitmap.height / 2
  131.   end
  132.   def visible=(val)
  133.     @arrow_sprite.visible = val if @arrow_sprite != nil
  134.     super(val)
  135.   end
  136.   def x=(new_x)
  137.     @arrow_sprite.x = new_x + @x_increment if @arrow_sprite != nil
  138.     super(new_x)
  139.   end
  140.   def y=(new_y)
  141.     @arrow_sprite.y = new_y + @y_increment if @arrow_sprite != nil
  142.     super(new_y)
  143.   end
  144.   def z=(new_z)
  145.     @arrow_sprite.z = new_z + 10 if @arrow_sprite != nil
  146.     super(new_z)
  147.   end
  148.   def start
  149.     self.visible = true
  150.     reset
  151.     for i in 0...16
  152.       self.x += 10
  153.       Graphics.update
  154.     end
  155.     @activated = true
  156.   end
  157.   def update
  158.     super
  159.   end
  160.   def dispose
  161.     @arrow_sprite.bitmap.dispose
  162.     @arrow_sprite.dispose
  163.     super
  164.   end
  165.   def reset
  166.     @x_increment = 16
  167.     self.x = -160
  168.     @time_count = 0
  169.     @state = 0
  170.     @result = false
  171.     refresh
  172.   end
  173.   def terminate(qte_result)
  174.     @result = qte_result
  175.     @activated = false
  176.     for i in 0...16
  177.       self.x -= 10
  178.       Graphics.update
  179.     end
  180.     self.visible = false
  181.   end
  182. end
  183.  
  184. class Window_QTE_Single < Window_QTE_Base
  185.   attr_writer   :keys
  186.   attr_writer   :success_fields
  187.   attr_accessor :non_mistake_mode
  188.   def initialize(keys, fields, non_mistake_mode = false)
  189.     super()
  190.     @keys = keys
  191.     @success_fields = fields
  192.     @non_mistake = non_mistake_mode
  193.     self.contents = Bitmap.new(width - 32, height - 32)
  194.     refresh
  195.   end
  196.   def refresh
  197.     self.contents.clear
  198.     text = QTE::ALL_KEYS[@keys[@state]] || ""
  199.     self.contents.draw_text(4, 0, 128, 32, "按下:" + text)
  200.     draw_bar
  201.   end
  202.   def draw_bar
  203.     w = 128
  204.     w1 = Integer((w-2) * @success_fields[@state][0] / 100.0)
  205.     w2 = Integer((w-2) * @success_fields[@state][1] / 100.0)
  206.     self.contents.fill_rect(0,48,w,8,Color.new(255,255,255,255))
  207.     self.contents.fill_rect(1,49,w-2,6,Color.new(0,0,0,255))
  208.     self.contents.fill_rect(w1,50,w2-w1,1,Color.new(0,150,0,255))
  209.     self.contents.fill_rect(w1,51,w2-w1,1,Color.new(0,200,0,255))
  210.     self.contents.fill_rect(w1,52,w2-w1,1,Color.new(0,150,0,255))
  211.   end
  212.   def update
  213.     super
  214.     update_arrow
  215.     if Input.key_trigger?
  216.       update_input
  217.     end
  218.     terminate(true) if @state == @keys.size
  219.     terminate(false) if @time_limit > 0 && @time_count > @time_limit
  220.   end
  221.   def update_arrow
  222.     if @time_limit == 0
  223.       if @time_count >= 100
  224.         @step = -4
  225.       end
  226.       if @time_count <= 0
  227.         @step = 4
  228.       end
  229.       @time_count += @step
  230.       @x_increment = 16 + Integer(@time_count * 128 / 100.0)
  231.     else
  232.       @time_count += 1
  233.       @x_increment = 16 + Integer(1.0 * @time_count * 128 / @time_limit)
  234.     end
  235.     @arrow_sprite.x = self.x + @x_increment
  236.   end
  237.   def update_input
  238.     if @time_limit == 0
  239.       in_field = @time_count <= @success_fields[@state][1] && @time_count >= @success_fields[@state][0]
  240.     else
  241.       time = 100.0 * @time_count / @time_limit
  242.       in_field = time <= @success_fields[@state][1] && time >= @success_fields[@state][0]
  243.     end
  244.     if Input.trigger?(@keys[@state]) && in_field
  245.       Audio.se_play(QTE::SUCCEEDED_SE)
  246.       @state += 1
  247.       @time_count = 0
  248.       refresh if @state < @keys.size
  249.     elsif @non_mistake_mode
  250.       Audio.se_play(QTE::FAILED_SE)
  251.       terminate(false)
  252.     end
  253.   end      
  254. end
  255. class Window_QTE_Combination < Window_QTE_Base
  256.   attr_reader :power
  257.   attr_writer :key_set
  258.   attr_writer :power_need
  259.   attr_writer :power_increment
  260.   attr_writer :power_decrement
  261.   def initialize(key_set, power_need, increment, decrement)
  262.     super()
  263.     @key_set = key_set
  264.     @state = 0
  265.     [url=home.php?mod=space&uid=28342]@power[/url] = 0
  266.     @power_need = power_need
  267.     @power_increment = increment
  268.     @power_decrement = decrement
  269.     self.time_limit = 0
  270.     self.contents = Bitmap.new(width - 32, height - 32)
  271.     refresh
  272.   end
  273.   def power=(val)
  274.     if [url=home.php?mod=space&uid=28342]@power[/url] != val
  275.       [url=home.php?mod=space&uid=28342]@power[/url] = val
  276.       if @power < 0
  277.         @power = 0
  278.       end
  279.       draw_bar
  280.     end
  281.   end
  282.   def reset
  283.     super
  284.     self.power = 0
  285.     @state = 0
  286.     if @time_limit == 0
  287.       @arrow_sprite.visible = false
  288.     end
  289.   end
  290.   def refresh
  291.     self.contents.clear
  292.     text = ""
  293.     for i in [email]0...@key_set.size[/email]
  294.       key = @key_set[i]
  295.       text += QTE::ALL_KEYS[@key_set[i]] || ""
  296.       text += "+" if i != @key_set.size - 1
  297.     end
  298.     self.contents.draw_text(4, 0, 128, 32, "猛击:" + text)
  299.     draw_bar
  300.   end
  301.   def draw_bar
  302.     w = 128
  303.     w1 = Integer(1.0 * (w-2) * @power / @power_need)
  304.     w1 = w-2 if w1 > w
  305.     self.contents.fill_rect(0,48,w,8,Color.new(255,255,255,255))
  306.     self.contents.fill_rect(1,49,w-2,6,Color.new(0,0,0,255))
  307.     self.contents.fill_rect(1,50,w1,1,Color.new(0,150,0,255))
  308.     self.contents.fill_rect(1,51,w1,1,Color.new(0,200,0,255))
  309.     self.contents.fill_rect(1,52,w1,1,Color.new(0,150,0,255))
  310.   end
  311.   def update
  312.     super
  313.     if @time_limit == 0
  314.       key = @key_set[@state]
  315.       if Input.trigger?(key)
  316.         self.power += @power_increment
  317.         @state += 1
  318.         @state %= @key_set.size
  319.       end
  320.       self.power -= @power_decrement
  321.       if @power >= @power_need
  322.         Audio.se_play(QTE::SUCCEEDED_SE)
  323.         terminate(true)
  324.         return
  325.       end
  326.     elsif @time_limit > 0
  327.       @time_count += 1
  328.       @x_increment = 16 + Integer(1.0 * @time_count * 128 / @time_limit)
  329.       @arrow_sprite.x = self.x + @x_increment
  330.       key = @key_set[@state]
  331.       if Input.trigger?(key)
  332.         self.power += @power_increment
  333.         @state += 1
  334.         @state %= @key_set.size
  335.       end
  336.       self.power -= @power_decrement
  337.       if @power >= @power_need
  338.         Audio.se_play(QTE::SUCCEEDED_SE)
  339.         terminate(true)
  340.         return
  341.       end
  342.       if @time_count >= @time_limit
  343.         Audio.se_play(QTE::FAILED_SE)
  344.         terminate(false)
  345.         return
  346.       end
  347.     end
  348.   end
  349. end
  350.  
  351. class Scene_Map
  352.   alias qte_main main
  353.   def main
  354.     @qte_single = Window_QTE_Single.new(Input::C, [0,100])
  355.     @qte_com = Window_QTE_Combination.new([Input::C], 500, 50, 0)
  356.     qte_main
  357.     @qte_single.dispose
  358.     @qte_com.dispose
  359.   end
  360.   alias qte_update update
  361.   def update
  362.     if @qte_single.activated
  363.       @qte_single.update
  364.       return
  365.     end
  366.     if @qte_com.activated
  367.       @qte_com.update
  368.       return
  369.     end
  370.     qte_update
  371.   end
  372.   def get_QTE_single
  373.     return @qte_single
  374.   end
  375.   def get_QTE_com
  376.     return @qte_com
  377.   end
  378. end
  379.  
  380. class Scene_Battle
  381.   alias qte_main main
  382.   def main
  383.     @qte_single = Window_QTE_Single.new(Input::C, [0,100])
  384.     @qte_com = Window_QTE_Combination.new([Input::C], 500, 50, 0)
  385.     qte_main
  386.     @qte_single.dispose
  387.     @qte_com.dispose
  388.   end
  389.   alias qte_update update
  390.   def update
  391.     if @qte_single.activated
  392.       @qte_single.update
  393.       return
  394.     end
  395.     if @qte_com.activated
  396.       @qte_com.update
  397.       return
  398.     end
  399.     qte_update
  400.   end
  401.   def get_QTE_single
  402.     return @qte_single
  403.   end
  404.   def get_QTE_com
  405.     return @qte_com
  406.   end
  407. end

附:几个QTE组件的设置图:
地图中的QTE开启示意图:

战斗QTE技能设置方法及判定示意图


地图中的QTE_Single:

战斗中的QTE_Combination:


范例附件: Project4.rar (203.41 KB, 下载次数: 674)

另外拜托版主去一下Url,这玩意出现在脚本里面太讨厌了-_-||     

点评

多谢你的建议!目前在战斗中的QTE效果不是很好,只能通过事件来实现,希望不要太麻烦  发表于 2014-11-3 08:41
提个建议,第二个敌人技能发动的QTE,最好是把技能对应的SP消耗为0,否则就会出现范例的情况,敌人没有足够的SP第二次发动技能。  发表于 2014-11-2 23:40
超好用,在我的游戏里,完全不必整合脚本直接可以用。等了好久啦~感谢!不过,我修改了一下,降低了难度。  发表于 2014-11-2 23:25
↓已添加附件  发表于 2014-6-16 18:50
可以打滚求范例吗_(:з」∠)_  发表于 2014-6-16 16:19

评分

参与人数 2星屑 +415 梦石 +1 收起 理由
青鸫 + 15 有大佬写QTE啦!!!!!(狂喜乱舞.
怪蜀黍 + 400 + 1 发布奖励

查看全部评分

Lv1.梦旅人

梦石
0
星屑
55
在线时间
119 小时
注册时间
2014-6-14
帖子
109
2
发表于 2014-6-16 14:08:48 | 只看该作者
挺强悍的
但是咱在游戏中最烦QTE
之前勿忘我直接把我给气爆炸了
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
85
在线时间
578 小时
注册时间
2010-6-29
帖子
365
3
发表于 2014-6-16 20:35:12 | 只看该作者
感觉第一种闪的好快!

点评

可以对时间限制进行调节,不过如果时间不受限制,闪得可能要快一些。如果觉得快了可以改203行和206行,把4改为2  发表于 2014-6-16 21:06
为了四公主苦逼赚钱中。
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
7921
在线时间
1049 小时
注册时间
2012-4-3
帖子
1271

开拓者

4
发表于 2014-6-17 11:09:33 手机端发表。 | 只看该作者
飞檐走壁,龙飞凤舞。值得琢磨琢磨。
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
671
在线时间
475 小时
注册时间
2011-4-25
帖子
166
5
发表于 2014-6-26 14:28:17 | 只看该作者
我记得MOG的VA脚本就有让人蛋疼的QTE插件,搞得我都想砸键盘
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
45 小时
注册时间
2010-8-21
帖子
53
6
发表于 2014-7-24 20:56:08 | 只看该作者
打滚时候发现,带走了谢谢分享~~~~~~~~~~
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
20431
在线时间
34 小时
注册时间
2014-3-10
帖子
1
7
发表于 2014-10-16 15:34:34 | 只看该作者
你好,请问一下现在这个插件的应用一直只提示同一个键(空格).
如果我想达到第一次提示按空格,第二次提示按LEFT,第三次提示按UP.....这样,随机一个键的效果,要如何设置呢?谢谢

点评

在qte执行前(单按键)用qte.key = INPUT :: LEFT可以更改按键设定  发表于 2014-10-22 18:25
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
37 小时
注册时间
2014-5-23
帖子
13
8
发表于 2014-10-21 17:41:20 | 只看该作者
我靠这个屌!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
211
在线时间
905 小时
注册时间
2010-9-6
帖子
3229
9
发表于 2014-11-2 21:47:53 | 只看该作者
很喜欢这个脚本,有个问题想问。在地图上出现的QTE,能不能别来回跑呢?就像是战斗QTE那样,过去了就过去了,随后直接判定。如果设置时间的话,会不会出现这种情况:时间条还没结束,就判定了?

点评

如果设置了时间,时间结束还没按到就算失败,不会预判。如果还是出现预判,请看脚本注释56行  发表于 2014-11-3 15:07
qte.time_limit可以设置时间限制,如果是固定时间限制,设置成正数,如果不需要时间限制,设置为0。所以设置为一个正数就不会循环跑了。  发表于 2014-11-3 15:06
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
12157
在线时间
4435 小时
注册时间
2014-4-11
帖子
5955

开拓者

10
发表于 2014-11-3 09:40:23 | 只看该作者
问题。
上面那个按空格图的情况。
左右速度可以调吗。
按到错误的地方没有效果,只有按到正确的位置才会结束。

点评

203 206行,@step的数值影响左右速度,太快可以调慢点。至于QTE失败的情况,只考虑逾期没按到的情况,按错键是不会失败的。  发表于 2014-11-3 15:04
我发现了。qte.time_limit = 0不等于0就可以了  发表于 2014-11-3 09:45
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-20 18:36

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表