Project1
标题:
【RGD工程迁移至RGU】脚本整合
[打印本页]
作者:
张咚咚
时间:
2022-2-7 13:14
标题:
【RGD工程迁移至RGU】脚本整合
本帖最后由 张咚咚 于 2022-12-16 15:43 编辑
以下为写的一些从RGD工程完美适配到RGU不报错的脚本。注:按需引用。
使用方法:将脚本插到脚本列表最上方。
#==============================================================================
# ■ 使用前置:该脚本是为了让使用RGD引擎的工程尽可能的兼容到RGU引擎上。
# 查看注释说明并根据需要引用即可。
# 因RGU搭载的ruby暂不支持DL模块, 如[原版/RGD]工程中使用到DL模块,
# 则需要手动配合RGU的Fiddle等自行进行修改。
#==============================================================================
#==============================================================================
# ■ Win32API
#------------------------------------------------------------------------------
# RGU 调用Win32API 返回的是 Fiddle::Pointer 对象,此脚本作用是将对象转换为字符串/整数。
#==============================================================================
class Win32API
alias :qqeat_rgd_win32api_initialize :initialize unless $@
def initialize(*args)
@ret = args[3]
qqeat_rgd_win32api_initialize(*args)
end
alias :qqeat_rgd_win32api_call :call unless $@
def call(*args)
res = qqeat_rgd_win32api_call(*args)
return nil if ['', nil, 'v', 'V'].include?(@ret)
return res.to_i if ['i', 'I', 'l', 'L'].include?(@ret)
res.to_s
end
# 其他调用方式
def Call(*args); call(*args); end
def [](*args); call(*args); end
end
#==============================================================================
# ■ Mouse
#==============================================================================
class << Mouse
#--------------------------------------------------------------------------
# ● 取滚轮位置, RGD 中向上/下滚动是返回 120/-120, 然后会在下一次Mouse.update后清除
# RGU则是向上滑滚轮值-1, 向下滑滚轮值+1, 此脚本作用是适配。
#--------------------------------------------------------------------------
alias :qqeat_rgd_mouse_scroll :scroll unless $@
@@save_scroll_value = 0; @@save_scroll_frames = {}
def scroll
v = qqeat_rgd_mouse_scroll
f = Graphics.frame_count
if sv = @@save_scroll_frames[f]
return sv
end
@@save_scroll_frames.clear
bv = @@save_scroll_value
@@save_scroll_value = v
@@save_scroll_frames[f] = v > bv ? 120 : (v < bv ? -120 : 0)
end
#--------------------------------------------------------------------------
# ● RGU 暂时还未实现clip方法, 声明一个空方法防止报错
#--------------------------------------------------------------------------
def clip(*args)
end
end
#==============================================================================
# ■ Graphics
#==============================================================================
class << Graphics
#--------------------------------------------------------------------------
# ● 获取全屏
#--------------------------------------------------------------------------
def is_fullscreen?
self.fullscreen
end
#--------------------------------------------------------------------------
# ● 切换全屏
#--------------------------------------------------------------------------
def toggle_fullscreen
self.fullscreen = !self.fullscreen
end
end
#==============================================================================
# ■ Input
#==============================================================================
class << Input
alias :qqeat_rgd_input_recent_triggered :recent_triggered unless $@
alias :qqeat_rgd_input_recent_pressed :recent_pressed unless $@
alias :qqeat_rgd_input_get_key_name :get_key_name unless $@
alias :qqeat_rgd_input_trigger? :trigger? unless $@
alias :qqeat_rgd_input_press? :press? unless $@
alias :qqeat_rgd_input_press_key? :press_key? unless $@
alias :qqeat_rgd_input_trigger_key? :trigger_key? unless $@
alias :qqeat_rgd_input_repeat_key? :repeat_key? unless $@
#--------------------------------------------------------------------------
# ● 获取RGD对应的键位
#--------------------------------------------------------------------------
RGD_KEYS = {
39 => 0x30, # 0
30 => 0x31, # 1
31 => 0x32, # 2
32 => 0x33, # 3
33 => 0x34, # 4
34 => 0x35, # 5
35 => 0x36, # 6
36 => 0x37, # 7
37 => 0x38, # 8
38 => 0x39, # 9
40 => 0x0D, # RETURN/ENTER
41 => 0x1B, # ESCAPE
42 => 0x08, # BACKSPACE
43 => 0x09, # TAB
44 => 0x20, # SPACE
45 => 0xBD, # -
46 => 0xBB, # =
57 => 0x14, # CAPSLOCK
58 => 0x70, # F1
59 => 0x71, # F2
60 => 0x72, # F3
61 => 0x73, # F4
62 => 0x74, # F5
63 => 0x75, # F6
64 => 0x76, # F7
65 => 0x77, # F8
66 => 0x78, # F9
67 => 0x79, # F10
68 => 0x7A, # F11
69 => 0x7B, # F12
70 => 0x2C, # SNAPSHOT/PRINTSCREEN
71 => 0x91, # SCROLL/SCROLLLOCK
72 => 0x13, # PAUSE
73 => 0x2D, # INSERT
74 => 0x24, # HOME
75 => 0x21, # PAGEUP
76 => 0x2E, # DELETE
77 => 0x23, # END
78 => 0x22, # PAGEDOWN
79 => 0x27, # RIGHT
80 => 0x25, # LEFT
81 => 0x28, # DOWN
82 => 0x26, # UP
83 => 0x90, # NUMLOCK
84 => 0x6F, # Numeric keypad /
85 => 0x6A, # Numeric keypad *
86 => 0xBD, # Numeric keypad -
87 => 0xBB, # Numeric keypad +
88 => 0x0D, # Numeric keypad ENTER
89 => 0x61, # Numeric keypad 1
90 => 0x62, # Numeric keypad 2
91 => 0x63, # Numeric keypad 3
92 => 0x64, # Numeric keypad 4
93 => 0x65, # Numeric keypad 5
94 => 0x66, # Numeric keypad 6
95 => 0x67, # Numeric keypad 7
96 => 0x68, # Numeric keypad 8
97 => 0x69, # Numeric keypad 9
98 => 0x60, # Numeric keypad 0
99 => 0xBE, # Numeric keypad .
104 => 0x7C, # F13
105 => 0x7D, # F14
106 => 0x7E, # F15
107 => 0x7F, # F16
108 => 0x80, # F17
109 => 0x81, # F18
110 => 0x82, # F19
111 => 0x83, # F20
112 => 0x84, # F21
113 => 0x85, # F22
114 => 0x86, # F23
115 => 0x87, # F24
116 => 0x2B, # EXECUTE
117 => 0x2F, # HELP
119 => 0x29, # SELECT
224 => 0xA2, # LCTRL/LCONTROL
228 => 0xA3, # RCTRL/RCONTROL
225 => 0xA0, # LSHIFT
229 => 0xA1, # RSHIFT
226 => 0xA4, # LALT
230 => 0xA5, # RALT
227 => 0x58, # LWIN/LGUI
231 => 0x5C, # RWIN/RGUI
}
def get_rgd_keys(k, reverse=false)
if reverse
return k - 61 if k.between?(65,90) # A~Z
return RGD_KEYS.key(k) || k
else
return k + 61 if k.between?(4,29) # A~Z
return RGD_KEYS[k] || k
end
end
#--------------------------------------------------------------------------
# ● recent_triggered, 返回的键码转换为 RGD 的键码
#--------------------------------------------------------------------------
def recent_triggered
k = qqeat_rgd_input_recent_triggered
get_rgd_keys(k)
end
#--------------------------------------------------------------------------
# ● recent_pressed, 返回的键码转换为 RGD 的键码
#--------------------------------------------------------------------------
def recent_pressed
k = qqeat_rgd_input_recent_pressed
get_rgd_keys(k)
end
#--------------------------------------------------------------------------
# ● press_key?, 判断的键码转换为 RGD/Windows 的键码
#--------------------------------------------------------------------------
def press_key?(k)
qqeat_rgd_input_press_key?(get_rgd_keys(k, true))
end
#--------------------------------------------------------------------------
# ● trigger_key?, 判断的键码转换为 RGD/Windows 的键码
#--------------------------------------------------------------------------
def trigger_key?(k)
qqeat_rgd_input_trigger_key?(get_rgd_keys(k, true))
end
#--------------------------------------------------------------------------
# ● repeat_key?, 判断的键码转换为 RGD/Windows 的键码
#--------------------------------------------------------------------------
def repeat_key?(k)
qqeat_rgd_input_repeat_key?(get_rgd_keys(k, true))
end
#--------------------------------------------------------------------------
# ● get_key_name
#--------------------------------------------------------------------------
def get_key_name(k)
k = get_rgd_keys(k, true)
qqeat_rgd_input_get_key_name(k)
end
#--------------------------------------------------------------------------
# ● trigger? 支持 F1~F12
#--------------------------------------------------------------------------
FKEYS = {
:F1 => 0x70, :F2 => 0x71, :F3 => 0x72, :F4 => 0x73, :F5 => 0x74,
:F6 => 0x75, :F7 => 0x76, :F8 => 0x77, :F9 => 0x78, :F10 => 0x79,
:F11 => 0x7A,:F12 => 0x7B,
}
def trigger?(k)
return recent_triggered == FKEYS[k] if FKEYS[k]
qqeat_rgd_input_trigger?(k)
end
#--------------------------------------------------------------------------
# ● press? 支持 F1~F12
#--------------------------------------------------------------------------
def press?(k)
return recent_pressed == FKEYS[k] if FKEYS[k]
qqeat_rgd_input_press?(k)
end
#--------------------------------------------------------------------------
# ● eval, 作用为在控制台输入脚本进行调试
#--------------------------------------------------------------------------
def eval(code)
begin
result = Kernel.eval(code, $binding)
print "=> "; p result
rescue Exception => e
puts e.to_s.force_encoding('UTF-8')
puts e.backtrace.map{|bt| bt.sub(/^{(\d+)}/){|item| "#{$RGSS_TITLES[$1.to_i]},#{item}" } }
end if code.length > 0
end
Thread.new{ Input.eval(gets.chomp) while true } if $TEST
end
$binding = binding
#==============================================================================
# ■ Bitmap
#==============================================================================
class Bitmap
#--------------------------------------------------------------------------
# ● 初始化, RGD 中允许Bitmap创建时宽高为0, RGU 需要设置最小为1
#--------------------------------------------------------------------------
alias :qqeat_rgd_bitmap_initialize :initialize unless $@
def initialize(*args)
if args.length == 2 # 支持创建 0 宽高的位图
args[0] = 1 if args[0] < 1
args[1] = 1 if args[1] < 1
end
qqeat_rgd_bitmap_initialize(*args)
end
#--------------------------------------------------------------------------
# ● RGU 该方法rect的宽高如果≤0则自动跳过, 在此适配为和原版一样的效果(原版设置为0其实是1的效果)
#--------------------------------------------------------------------------
alias :qqeat_rgd_bitmap_stretch_blt :stretch_blt unless $@
def stretch_blt(*args)
dest_rect = args[0]
src_rect = args[2]
if dest_rect.width <= 0 or dest_rect.height <= 0
dest_rect = dest_rect.dup
dest_rect.width = [dest_rect.width, 1].max
dest_rect.height = [dest_rect.height, 1].max
args[0] = dest_rect
end
if src_rect.width <= 0 or src_rect.height <= 0
src_rect = src_rect.dup
src_rect.width = [src_rect.width, 1].max
src_rect.height = [src_rect.height, 1].max
args[2] = src_rect
end
qqeat_rgd_bitmap_stretch_blt(*args)
end
end
#==============================================================================
# ■ Sprite
#------------------------------------------------------------------------------
# Sprite
#==============================================================================
class Sprite
#--------------------------------------------------------------------------
# ● 重载赋值
#--------------------------------------------------------------------------
alias :qqeat_rgd_sprite_tone_set :tone= unless $@
def tone=(t)
self.tone.instance_variables.each do |sym|
self.tone.remove_instance_variable(sym)
end
t.instance_variables.each do |sym|
self.tone.instance_variable_set(sym, t.instance_variable_get(sym))
end
qqeat_rgd_sprite_tone_set(t)
end
#--------------------------------------------------------------------------
# ● RGU 只允许传布尔值(2022.11.13之后的RGU版本已适配)
#--------------------------------------------------------------------------
alias :qqeat_rgd_sprite_visible_set :visible= unless $@
def visible=(v)
qqeat_rgd_sprite_visible_set(!!v)
end
#--------------------------------------------------------------------------
# ● RGU 暂未有该方法, 先用来占个位
#--------------------------------------------------------------------------
def shear_x; 1.0; end
def shear_y; 1.0; end
def shear_x=(v); end
def shear_y=(v); end
end
#==============================================================================
# ■ Color
#------------------------------------------------------------------------------
# Color
#==============================================================================
class Color
#--------------------------------------------------------------------------
# ● 存储
#--------------------------------------------------------------------------
def _dump(depth = 0)
[red, green, blue, alpha].pack('D*') # 使用原版RM的编码方式进行存储
end
#--------------------------------------------------------------------------
# ● 读取
# Marshl 存储区别
# RGD, 使用 1字节(Byte) *rgba = 4字节存储, 排列为 bgra
# 原版/RGU, 使用 8字节(Double)*rgba = 32字节存储, 排列为 rgba
#--------------------------------------------------------------------------
def self._load(string)
if string.length == 4 # RGD 解码
arr = string.unpack('C*')
arr = [arr[2], arr[1], arr[0], arr[3]]
else # 原版/RGU 解码
arr = string.unpack('D*')
end
self.new(*arr)
end
end
#==============================================================================
# ■ Tone
#------------------------------------------------------------------------------
# Tone
#==============================================================================
class Tone
#--------------------------------------------------------------------------
# ● 存储
#--------------------------------------------------------------------------
def _dump(depth = 0)
[red, green, blue, gray].pack('D*') # 使用原版RM的编码方式进行存储
end
#--------------------------------------------------------------------------
# ● 读取
# Marshl 存储区别
# RGD, 使用 4字节(Integer)*rgba = 16字节存储, 排列为 rgbg
# 原版/RGU, 使用 8字节(Double) *rgba = 32字节存储, 排列为 rgbg
#--------------------------------------------------------------------------
def self._load(string)
arr = string.unpack(string.length == 16 ? 'i*' : 'D*')
self.new(*arr)
end
end
#==============================================================================
# ■ Viewport
#------------------------------------------------------------------------------
# Viewport
#==============================================================================
class Viewport
#--------------------------------------------------------------------------
# ● RGU 只允许传布尔值(2022.11.13之后的RGU版本已适配)
#--------------------------------------------------------------------------
alias :qqeat_rgd_viewport_visible_set :visible= unless $@
def visible=(v)
qqeat_rgd_viewport_visible_set(!!v)
end
end
#==============================================================================
# ■ Hash
#==============================================================================
class Hash
#--------------------------------------------------------------------------
# ● 在原版RM 使用的 ruby 1.9.2 版本中是存在 Hash#index 方法的,用途是根据value取key。
# 在RGU使用的 ruby 3.0.0 中貌似不存在该方法,此处为手动实现一个。
#--------------------------------------------------------------------------
def index(v)
i = self.values.index(v) and self.keys[i]
end
end
#==============================================================================
# ■ NilClass
#==============================================================================
class NilClass
#--------------------------------------------------------------------------
# ● Ruby 高版本的 NilClass 类不存在 instance_variable_set 方法, 特此兼容处理防报错
#--------------------------------------------------------------------------
def instance_variable_set(*args); end
end
$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