Project1

标题: 【RGD工程迁移至RGU】脚本整合 [打印本页]

作者: 张咚咚    时间: 2022-2-7 13:14
标题: 【RGD工程迁移至RGU】脚本整合
本帖最后由 张咚咚 于 2022-12-16 15:43 编辑

以下为写的一些从RGD工程完美适配到RGU不报错的脚本。注:按需引用。
使用方法:将脚本插到脚本列表最上方。

  1. #==============================================================================
  2. # ■ 使用前置:该脚本是为了让使用RGD引擎的工程尽可能的兼容到RGU引擎上。
  3. #                    查看注释说明并根据需要引用即可。
  4. #                    因RGU搭载的ruby暂不支持DL模块, 如[原版/RGD]工程中使用到DL模块,
  5. #                    则需要手动配合RGU的Fiddle等自行进行修改。
  6. #==============================================================================

  7. #==============================================================================
  8. # ■ Win32API
  9. #------------------------------------------------------------------------------
  10. #  RGU 调用Win32API 返回的是 Fiddle::Pointer 对象,此脚本作用是将对象转换为字符串/整数。
  11. #==============================================================================

  12. class Win32API
  13.   alias :qqeat_rgd_win32api_initialize :initialize unless $@
  14.   def initialize(*args)
  15.     @ret = args[3]
  16.     qqeat_rgd_win32api_initialize(*args)
  17.   end
  18.   alias :qqeat_rgd_win32api_call :call unless $@
  19.   def call(*args)
  20.     res = qqeat_rgd_win32api_call(*args)
  21.     return nil if ['', nil, 'v', 'V'].include?(@ret)
  22.     return res.to_i if ['i', 'I', 'l', 'L'].include?(@ret)
  23.     res.to_s
  24.   end
  25.   # 其他调用方式
  26.   def Call(*args); call(*args); end
  27.   def [](*args); call(*args); end
  28. end


  29. #==============================================================================
  30. # ■ Mouse
  31. #==============================================================================

  32. class << Mouse
  33.   #--------------------------------------------------------------------------
  34.   # ● 取滚轮位置, RGD 中向上/下滚动是返回 120/-120, 然后会在下一次Mouse.update后清除
  35.   #    RGU则是向上滑滚轮值-1, 向下滑滚轮值+1, 此脚本作用是适配。
  36.   #--------------------------------------------------------------------------
  37.   alias :qqeat_rgd_mouse_scroll :scroll unless $@
  38.   @@save_scroll_value = 0; @@save_scroll_frames = {}
  39.   def scroll
  40.     v = qqeat_rgd_mouse_scroll
  41.     f = Graphics.frame_count
  42.     if sv = @@save_scroll_frames[f]
  43.       return sv
  44.     end
  45.     @@save_scroll_frames.clear
  46.     bv = @@save_scroll_value
  47.     @@save_scroll_value = v
  48.     @@save_scroll_frames[f] = v > bv ? 120 : (v < bv ? -120 : 0)
  49.   end
  50.   #--------------------------------------------------------------------------
  51.   # ● RGU 暂时还未实现clip方法, 声明一个空方法防止报错
  52.   #--------------------------------------------------------------------------
  53.   def clip(*args)
  54.   end
  55. end

  56. #==============================================================================
  57. # ■ Graphics
  58. #==============================================================================

  59. class << Graphics
  60.   #--------------------------------------------------------------------------
  61.   # ● 获取全屏
  62.   #--------------------------------------------------------------------------
  63.   def is_fullscreen?
  64.     self.fullscreen
  65.   end
  66.   #--------------------------------------------------------------------------
  67.   # ● 切换全屏
  68.   #--------------------------------------------------------------------------
  69.   def toggle_fullscreen
  70.     self.fullscreen = !self.fullscreen
  71.   end
  72. end

  73. #==============================================================================
  74. # ■ Input
  75. #==============================================================================

  76. class << Input
  77.   alias :qqeat_rgd_input_recent_triggered :recent_triggered unless $@
  78.   alias :qqeat_rgd_input_recent_pressed :recent_pressed unless $@
  79.   alias :qqeat_rgd_input_get_key_name :get_key_name unless $@
  80.   alias :qqeat_rgd_input_trigger? :trigger? unless $@
  81.   alias :qqeat_rgd_input_press? :press? unless $@
  82.   alias :qqeat_rgd_input_press_key? :press_key? unless $@
  83.   alias :qqeat_rgd_input_trigger_key? :trigger_key? unless $@
  84.   alias :qqeat_rgd_input_repeat_key? :repeat_key? unless $@
  85.   #--------------------------------------------------------------------------
  86.   # ● 获取RGD对应的键位
  87.   #--------------------------------------------------------------------------
  88.   RGD_KEYS = {
  89.     39 => 0x30, # 0
  90.     30 => 0x31, # 1
  91.     31 => 0x32, # 2
  92.     32 => 0x33, # 3
  93.     33 => 0x34, # 4
  94.     34 => 0x35, # 5
  95.     35 => 0x36, # 6
  96.     36 => 0x37, # 7
  97.     37 => 0x38, # 8
  98.     38 => 0x39, # 9
  99.     40 => 0x0D, # RETURN/ENTER
  100.     41 => 0x1B, # ESCAPE
  101.     42 => 0x08, # BACKSPACE
  102.     43 => 0x09, # TAB
  103.     44 => 0x20, # SPACE
  104.     45 => 0xBD, # -
  105.     46 => 0xBB, # =
  106.     57 => 0x14, # CAPSLOCK
  107.     58 => 0x70, # F1
  108.     59 => 0x71, # F2
  109.     60 => 0x72, # F3
  110.     61 => 0x73, # F4
  111.     62 => 0x74, # F5
  112.     63 => 0x75, # F6
  113.     64 => 0x76, # F7
  114.     65 => 0x77, # F8
  115.     66 => 0x78, # F9
  116.     67 => 0x79, # F10
  117.     68 => 0x7A, # F11
  118.     69 => 0x7B, # F12
  119.     70 => 0x2C, # SNAPSHOT/PRINTSCREEN
  120.     71 => 0x91, # SCROLL/SCROLLLOCK
  121.     72 => 0x13, # PAUSE
  122.     73 => 0x2D, # INSERT
  123.     74 => 0x24, # HOME
  124.     75 => 0x21, # PAGEUP
  125.     76 => 0x2E, # DELETE
  126.     77 => 0x23, # END
  127.     78 => 0x22, # PAGEDOWN
  128.     79 => 0x27, # RIGHT
  129.     80 => 0x25, # LEFT
  130.     81 => 0x28, # DOWN
  131.     82 => 0x26, # UP
  132.     83 => 0x90, # NUMLOCK
  133.     84 => 0x6F, # Numeric keypad /
  134.     85 => 0x6A, # Numeric keypad *
  135.     86 => 0xBD, # Numeric keypad -
  136.     87 => 0xBB, # Numeric keypad +
  137.     88 => 0x0D, # Numeric keypad ENTER
  138.     89 => 0x61, # Numeric keypad 1
  139.     90 => 0x62, # Numeric keypad 2
  140.     91 => 0x63, # Numeric keypad 3
  141.     92 => 0x64, # Numeric keypad 4
  142.     93 => 0x65, # Numeric keypad 5
  143.     94 => 0x66, # Numeric keypad 6
  144.     95 => 0x67, # Numeric keypad 7
  145.     96 => 0x68, # Numeric keypad 8
  146.     97 => 0x69, # Numeric keypad 9
  147.     98 => 0x60, # Numeric keypad 0
  148.     99 => 0xBE, # Numeric keypad .
  149.     104 => 0x7C, # F13
  150.     105 => 0x7D, # F14
  151.     106 => 0x7E, # F15
  152.     107 => 0x7F, # F16
  153.     108 => 0x80, # F17
  154.     109 => 0x81, # F18
  155.     110 => 0x82, # F19
  156.     111 => 0x83, # F20
  157.     112 => 0x84, # F21
  158.     113 => 0x85, # F22
  159.     114 => 0x86, # F23
  160.     115 => 0x87, # F24
  161.     116 => 0x2B, # EXECUTE
  162.     117 => 0x2F, # HELP
  163.     119 => 0x29, # SELECT
  164.     224 => 0xA2, # LCTRL/LCONTROL
  165.     228 => 0xA3, # RCTRL/RCONTROL
  166.     225 => 0xA0, # LSHIFT
  167.     229 => 0xA1, # RSHIFT
  168.     226 => 0xA4, # LALT
  169.     230 => 0xA5, # RALT
  170.     227 => 0x58, # LWIN/LGUI
  171.     231 => 0x5C, # RWIN/RGUI
  172.   }
  173.   def get_rgd_keys(k, reverse=false)
  174.     if reverse
  175.       return k - 61 if k.between?(65,90) # A~Z
  176.       return RGD_KEYS.key(k) || k
  177.     else
  178.       return k + 61 if k.between?(4,29) # A~Z
  179.       return RGD_KEYS[k] || k
  180.     end
  181.   end
  182.   #--------------------------------------------------------------------------
  183.   # ● recent_triggered, 返回的键码转换为 RGD 的键码
  184.   #--------------------------------------------------------------------------
  185.   def recent_triggered
  186.     k = qqeat_rgd_input_recent_triggered
  187.     get_rgd_keys(k)
  188.   end
  189.   #--------------------------------------------------------------------------
  190.   # ● recent_pressed, 返回的键码转换为 RGD 的键码
  191.   #--------------------------------------------------------------------------
  192.   def recent_pressed
  193.     k = qqeat_rgd_input_recent_pressed
  194.     get_rgd_keys(k)
  195.   end
  196.   #--------------------------------------------------------------------------
  197.   # ● press_key?, 判断的键码转换为 RGD/Windows 的键码
  198.   #--------------------------------------------------------------------------
  199.   def press_key?(k)
  200.     qqeat_rgd_input_press_key?(get_rgd_keys(k, true))
  201.   end
  202.   #--------------------------------------------------------------------------
  203.   # ● trigger_key?, 判断的键码转换为 RGD/Windows 的键码
  204.   #--------------------------------------------------------------------------
  205.   def trigger_key?(k)
  206.     qqeat_rgd_input_trigger_key?(get_rgd_keys(k, true))
  207.   end
  208.   #--------------------------------------------------------------------------
  209.   # ● repeat_key?, 判断的键码转换为 RGD/Windows 的键码
  210.   #--------------------------------------------------------------------------
  211.   def repeat_key?(k)
  212.     qqeat_rgd_input_repeat_key?(get_rgd_keys(k, true))
  213.   end
  214.   #--------------------------------------------------------------------------
  215.   # ● get_key_name
  216.   #--------------------------------------------------------------------------
  217.   def get_key_name(k)
  218.     k = get_rgd_keys(k, true)
  219.     qqeat_rgd_input_get_key_name(k)
  220.   end
  221.   #--------------------------------------------------------------------------
  222.   # ● trigger? 支持 F1~F12
  223.   #--------------------------------------------------------------------------
  224.   FKEYS = {
  225.     :F1 => 0x70, :F2 => 0x71, :F3 => 0x72, :F4 => 0x73, :F5 => 0x74,
  226.     :F6 => 0x75, :F7 => 0x76, :F8 => 0x77, :F9 => 0x78, :F10 => 0x79,
  227.     :F11 => 0x7A,:F12 => 0x7B,
  228.   }
  229.   def trigger?(k)
  230.     return recent_triggered == FKEYS[k] if FKEYS[k]
  231.     qqeat_rgd_input_trigger?(k)
  232.   end
  233.   #--------------------------------------------------------------------------
  234.   # ● press? 支持 F1~F12
  235.   #--------------------------------------------------------------------------
  236.   def press?(k)
  237.     return recent_pressed == FKEYS[k] if FKEYS[k]
  238.     qqeat_rgd_input_press?(k)
  239.   end
  240.   #--------------------------------------------------------------------------
  241.   # ● eval, 作用为在控制台输入脚本进行调试
  242.   #--------------------------------------------------------------------------
  243.   def eval(code)
  244.     begin
  245.       result = Kernel.eval(code, $binding)
  246.       print "=> "; p result
  247.     rescue Exception => e
  248.       puts e.to_s.force_encoding('UTF-8')
  249.       puts e.backtrace.map{|bt| bt.sub(/^{(\d+)}/){|item| "#{$RGSS_TITLES[$1.to_i]},#{item}" } }
  250.     end if code.length > 0
  251.   end
  252.   Thread.new{ Input.eval(gets.chomp) while true } if $TEST
  253. end
  254. $binding = binding

  255. #==============================================================================
  256. # ■ Bitmap
  257. #==============================================================================

  258. class Bitmap
  259.   #--------------------------------------------------------------------------
  260.   # ● 初始化, RGD 中允许Bitmap创建时宽高为0, RGU 需要设置最小为1
  261.   #--------------------------------------------------------------------------
  262.   alias :qqeat_rgd_bitmap_initialize :initialize unless $@
  263.   def initialize(*args)
  264.     if args.length == 2 # 支持创建 0 宽高的位图
  265.       args[0] = 1 if args[0] < 1
  266.       args[1] = 1 if args[1] < 1
  267.     end
  268.     qqeat_rgd_bitmap_initialize(*args)
  269.   end
  270.   #--------------------------------------------------------------------------
  271.   # ● RGU 该方法rect的宽高如果≤0则自动跳过, 在此适配为和原版一样的效果(原版设置为0其实是1的效果)
  272.   #--------------------------------------------------------------------------
  273.   alias :qqeat_rgd_bitmap_stretch_blt :stretch_blt unless $@
  274.   def stretch_blt(*args)
  275.     dest_rect = args[0]
  276.     src_rect = args[2]
  277.     if dest_rect.width <= 0 or dest_rect.height <= 0
  278.       dest_rect = dest_rect.dup
  279.       dest_rect.width = [dest_rect.width, 1].max
  280.       dest_rect.height = [dest_rect.height, 1].max
  281.       args[0] = dest_rect
  282.     end
  283.     if src_rect.width <= 0 or src_rect.height <= 0
  284.       src_rect = src_rect.dup
  285.       src_rect.width = [src_rect.width, 1].max
  286.       src_rect.height = [src_rect.height, 1].max
  287.       args[2] = src_rect
  288.     end
  289.     qqeat_rgd_bitmap_stretch_blt(*args)
  290.   end
  291. end

  292. #==============================================================================
  293. # ■ Sprite
  294. #------------------------------------------------------------------------------
  295. #  Sprite
  296. #==============================================================================

  297. class Sprite
  298.   #--------------------------------------------------------------------------
  299.   # ● 重载赋值
  300.   #--------------------------------------------------------------------------
  301.   alias :qqeat_rgd_sprite_tone_set :tone= unless $@
  302.   def tone=(t)
  303.     self.tone.instance_variables.each do |sym|
  304.       self.tone.remove_instance_variable(sym)
  305.     end
  306.     t.instance_variables.each do |sym|
  307.       self.tone.instance_variable_set(sym, t.instance_variable_get(sym))
  308.     end
  309.     qqeat_rgd_sprite_tone_set(t)
  310.   end
  311.   #--------------------------------------------------------------------------
  312.   # ● RGU 只允许传布尔值(2022.11.13之后的RGU版本已适配)
  313.   #--------------------------------------------------------------------------
  314.   alias :qqeat_rgd_sprite_visible_set :visible= unless $@
  315.   def visible=(v)
  316.     qqeat_rgd_sprite_visible_set(!!v)
  317.   end
  318.   #--------------------------------------------------------------------------
  319.   # ● RGU 暂未有该方法, 先用来占个位
  320.   #--------------------------------------------------------------------------
  321.   def shear_x; 1.0; end
  322.   def shear_y; 1.0; end
  323.   def shear_x=(v); end
  324.   def shear_y=(v); end
  325. end

  326. #==============================================================================
  327. # ■ Color
  328. #------------------------------------------------------------------------------
  329. #  Color
  330. #==============================================================================

  331. class Color
  332.   #--------------------------------------------------------------------------
  333.   # ● 存储
  334.   #--------------------------------------------------------------------------
  335.   def _dump(depth = 0)
  336.     [red, green, blue, alpha].pack('D*') # 使用原版RM的编码方式进行存储
  337.   end
  338.   #--------------------------------------------------------------------------
  339.   # ● 读取
  340.   #    Marshl 存储区别
  341.   #     RGD,      使用 1字节(Byte)  *rgba = 4字节存储, 排列为 bgra
  342.   #     原版/RGU, 使用 8字节(Double)*rgba = 32字节存储, 排列为 rgba
  343.   #--------------------------------------------------------------------------
  344.   def self._load(string)
  345.     if string.length == 4 # RGD 解码
  346.       arr = string.unpack('C*')
  347.       arr = [arr[2], arr[1], arr[0], arr[3]]
  348.     else # 原版/RGU 解码
  349.       arr = string.unpack('D*')
  350.     end
  351.     self.new(*arr)
  352.   end
  353. end

  354. #==============================================================================
  355. # ■ Tone
  356. #------------------------------------------------------------------------------
  357. #  Tone
  358. #==============================================================================

  359. class Tone
  360.   #--------------------------------------------------------------------------
  361.   # ● 存储
  362.   #--------------------------------------------------------------------------
  363.   def _dump(depth = 0)
  364.     [red, green, blue, gray].pack('D*') # 使用原版RM的编码方式进行存储
  365.   end
  366.   #--------------------------------------------------------------------------
  367.   # ● 读取
  368.   #    Marshl 存储区别
  369.   #     RGD,      使用 4字节(Integer)*rgba = 16字节存储, 排列为 rgbg
  370.   #     原版/RGU, 使用 8字节(Double) *rgba = 32字节存储, 排列为 rgbg
  371.   #--------------------------------------------------------------------------
  372.   def self._load(string)
  373.     arr = string.unpack(string.length == 16 ? 'i*' : 'D*')
  374.     self.new(*arr)
  375.   end
  376. end

  377. #==============================================================================
  378. # ■ Viewport
  379. #------------------------------------------------------------------------------
  380. #  Viewport
  381. #==============================================================================

  382. class Viewport
  383.   #--------------------------------------------------------------------------
  384.   # ● RGU 只允许传布尔值(2022.11.13之后的RGU版本已适配)
  385.   #--------------------------------------------------------------------------
  386.   alias :qqeat_rgd_viewport_visible_set :visible= unless $@
  387.   def visible=(v)
  388.     qqeat_rgd_viewport_visible_set(!!v)
  389.   end
  390. end

  391. #==============================================================================
  392. # ■ Hash
  393. #==============================================================================

  394. class Hash
  395.   #--------------------------------------------------------------------------
  396.   # ● 在原版RM 使用的 ruby 1.9.2 版本中是存在 Hash#index 方法的,用途是根据value取key。
  397.   #  在RGU使用的 ruby 3.0.0 中貌似不存在该方法,此处为手动实现一个。
  398.   #--------------------------------------------------------------------------
  399.   def index(v)
  400.     i = self.values.index(v) and self.keys[i]
  401.   end
  402. end

  403. #==============================================================================
  404. # ■ NilClass
  405. #==============================================================================

  406. class NilClass
  407.   #--------------------------------------------------------------------------
  408.   # ● Ruby 高版本的 NilClass 类不存在 instance_variable_set 方法, 特此兼容处理防报错
  409.   #--------------------------------------------------------------------------
  410.   def instance_variable_set(*args); end
  411. end

  412. $RGU = true if Runtime
复制代码


关于从RGD适配过来额外的需要注意的一些问题。
1.在写文件时, 需要检查一下编码, 不然可能会报错。
2.在使用MoveWindow API移动窗口位置时,可能会导致游戏窗口变得很小。
3.音频格式目前支持ogg、mp3等,wav等特殊音频格式不支持需要注意一下(或许后续会支持)。
4.Bitmap#process_color 中的回调参数脱离了块后不可以调用。v = nil; process_color{|arr| v = arr }; p v # 会闪退
5.在非主线程中操作Bitmap可能会有问题。


有其他的问题,可以在下面回复。
作者: ppspssss    时间: 2022-2-7 17:14
我看了你的RGD对比发射多个弹幕的GIF, 貌似比RGD还要效率高很多




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1