赞 342
VIP 10
好人卡 8
积分 262
经验 235776
最后登录 2024-9-23
在线时间 2387 小时
Lv5.捕梦者 (版主 )
遠航の猫咪
梦石 3
星屑 23186
在线时间 2387 小时
注册时间 2005-10-15
帖子 1166
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
名字带SEP,实际上并不依赖于SEP核心插件,可以独立插入使用。
恩,只是为了造一个功能比较全面(就是键比较全)并且低冲突可能的轮子而已。
键名是从.Net core里的常量表导出的,应该不会更多了……我自己的加强版118键键盘上的键都按通过了。
判定方法是
Keyboard.press?(键名)
Keyboard.trigger?(键名)
Keyboard.repeat?(键名),关于repeat的表现可以自己设定(由于RM一帧更新一次的限制,只能以帧为单位设定)
这些和Input类的使用是一样的
键名可以是真正的常量表的名字,比如Keyboard::A
也可以简写为:A
还可以用数组写成[:A, :B, :C],任意一个键按下均判定为真
还可以……写成"A"甚至"a",后台会自动映射为真实键名
注入了Input.update,只要调用Input.update就可以更新全键盘状态
但是,没有像夏娜版的全键盘一样把判定也注入进去,并不是因为注入不了。
原因是为了兼容键名的多种写法,不可避免的会和Input::A, Input::X这样的名称冲突。
RM的A并不是键盘上的A,地球人都知道——
我也一度试图注入把Input::A重新定义为[:L_SHIFT, :R_SHIFT, :Z],但想用户(玩家,不是开发者)按F1可以自己修改这种定义……所以最后放弃了。
最后,欢迎测试。
#==============================================================================
# ■ SEP 全键盘处理 v1.0 by SailCat
#------------------------------------------------------------------------------
# 方法:本脚本插入Main之前使用
# 依赖:无
# 版本:v1.0 (Build 180110)
# 效果:
# 1. 全键盘按键响应
# 2. 注入Input模块的update处理
# 3. Lock键、Shift/Ctrl/Alt/Win键状态的响应
# 4. 获得输入的字符
# 配置:重复延迟和重复间隔速率
# 冲突:其他类似脚本
# 说明:
# 1. 调用全键盘方法为Keyboard.press?(键名常量、符号或字符)。
# 2. 上述press?也可替换为trigger?或repeat?,含义与Input中的同名方法相同。
# 3. 其他检测包括对于Lock键的状态,Shift/Ctrl/Alt/Win的状态检测等。
# 4. 使用Keyboard.type_char可以获得打字键入的字符。
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
$sailcat_import ||= { }
#--------------------------------------------------------------------------
# ● 脚本配置区
#--------------------------------------------------------------------------
module Keyboard_Config
REPEAT_DELAY = 8 # 首次重复前的延迟值(帧)
REPEAT_SPEED = 2 # 每次重复按键的间隔(帧),越大越慢
#--------------------------------------------------------------------------
# ● 配置检查,请勿更改
#--------------------------------------------------------------------------
unless REPEAT_SPEED > 0
raise "重复按键的间隔不能低于1帧"
end
end
#--------------------------------------------------------------------------
# ● 植入
#--------------------------------------------------------------------------
$sailcat_import [ :Keyboard ] = 1.0
end
#==============================================================================
# ■ 全键盘处理核心
#==============================================================================
module Keyboard
include SailCat::Keyboard_Config
#--------------------------------------------------------------------------
# ● 常量
#--------------------------------------------------------------------------
NONE = 0
L_BUTTON, R_BUTTON, CANCEL, M_BUTTON, X_BUTTON1, X_BUTTON2 = *1 ..6
BACKSPACE, TAB, LINE_FEED, V_TAB, CLEAR, ENTER = *8 ..13
SHIFT_KEY, CONTROL_KEY, ALT_KEY, PAUSE_KEY = *16 ..19
CAPS_LOCK, KANA_MODE, JUNJA_MODE, DUMMY, FINAL_MODE, KANJI_MODE = *20 ..25
ESCAPE, IME_CONVERT, IME_NONCONVERT, IME_ACCEPT, IME_MODECHANGE = *27 ..31
SPACE, PAGEUP, PAGEDOWN, ENDKEY, HOME, LEFT, UP, RIGHT, DOWN = *32 ..40
SELECT , PRINT , EXECUTE, PRINTSCREEN, INSERT, DELETE, HELP = *41 ..47
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 = *48 ..57
A, B, C, D, E, F, G, H, I, J, K, L, M = *65 ..77
N, O, P , Q, R, S, T, U, V, W, X, Y, Z = *78 ..90
LWIN, RWIN, APPS, SLEEP = 91 , 92 , 93 , 95
NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9 = *96 ..105
MULTIPLY, ADD, SEPARATOR, SUBTRACT, DECIMAL, DIVIDE = *106 ..111
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 = *112 ..123
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24 = *124 ..135
NUM_LOCK, SCROLL_LOCK = 144 , 145
L_SHIFT, R_SHIFT, L_CTRL, R_CTRL, L_ALT, R_ALT = *160 ..165
B_BACK, B_FORWARD, B_REFRESH, B_STOP, B_SEARCH, B_FAVOR, B_HOME = *166 ..172
VOL_MUTE, VOL_DOWN, VOL_UP = *173 ..175
MEDIA_NEXT, MEDIA_PREVIOUS, MEDIA_STOP, MEDIA_PLAYPAUSE = *176 ..179
LAUNCH_MAIL, SELECT_MEDIA, LAUNCH_APP1, LAUNCH_APP2 = *180 ..183
SEMICOLON, PLUS, COMMA, MINUS, PERIOD, QUESTION, TILDE = *186 ..192
L_BRACE, PIPE, R_BRACE, QUOTE, OEM8 = *219 ..223
BACKSLASH, PROCESS_KEY, PACKET = 226 , 229 , 231
ATTN, CRSEL, EXSEL, ERASE_EOF, PLAY, ZOOM, NONAME, PA1, OEM_CLEAR = *246 ..254
ANY_BUTTON = [ 1 , 2 , 4 , 5 , 6 ]
ANY_KEY = [ 8 ..13 , 27 , 32 ..57 , 65 ..90 , 96 ..135 , 186 ..192 , 219 ..223 ] .map do |x|
x.to_a
end .flatten
#--------------------------------------------------------------------------
# ● API
#--------------------------------------------------------------------------
GetAsyncKeyState = Win32API.new ( "user32" , "GetAsyncKeyState" , "i" , "i" )
GetKeyState = Win32API.new ( "user32" , "GetKeyState" , "i" , "i" )
#--------------------------------------------------------------------------
# ● 用于检测重复按键的标记器
#--------------------------------------------------------------------------
Flags = { }
#--------------------------------------------------------------------------
# ● 更新键盘输入,该方法每帧调用1次
#--------------------------------------------------------------------------
def self .update
Flags.each_key do |k|
GetAsyncKeyState.call ( k) & 32768 != 0 ? Flags[ k] += 1 : Flags.delete ( k)
end
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否现在被按下
#--------------------------------------------------------------------------
def self .press ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| press?( k) } if key.is_a ?( Array )
GetAsyncKeyState.call ( key) != 0 ? ( Flags[ key] ||= 0 ; true ) : false
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重新被按下
#--------------------------------------------------------------------------
def self .trigger ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| trigger?( k) } if key.is_a ?( Array )
Flags[ key] ? Flags[ key] == 0 : press?( key)
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重复被按下
#--------------------------------------------------------------------------
def self .repeat ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| repeat?( k) } if key.is_a ?( Array )
Flags[ key] ? ( Flags[ key] >= REPEAT_DELAY and ( Flags[ key] - REPEAT_DELAY) %
REPEAT_SPEED == 0 ) : press?( key)
end
#--------------------------------------------------------------------------
# ● 键盘状态判断
#--------------------------------------------------------------------------
def self .lock ?( key) ; GetKeyState.call ( key) & 1 == 1 ; end
def self .caps_lock ?; lock?( CAPS_LOCK) ; end
def self .num_lock ?; lock?( NUM_LOCK) ; end
def self .scroll_lock ?; lock?( SCROLL_LOCK) ; end
#--------------------------------------------------------------------------
# ● 修饰键判断
#--------------------------------------------------------------------------
def self .shift ?; press?( [ SHIFT_KEY, L_SHIFT, R_SHIFT] ) ; end
def self .ctrl ?; press?( [ CONTROL_KEY, L_CTRL, R_CTRL] ) ; end
def self .alt ?; press?( [ ALT_KEY, L_ALT, R_ALT] ) ; end
def self .win ?; press?( [ L_WIN, R_WIN] ) ; end
#--------------------------------------------------------------------------
# ● 当前按下的键名
#--------------------------------------------------------------------------
def self .key_code
a = ANY_KEY.select { |key| repeat?( key) }
a.empty ? ? 0 : a[ 0 ]
end
#--------------------------------------------------------------------------
# ● 当前输入的字符
#--------------------------------------------------------------------------
def self .type_char
k = key_code
k == 0 ? "" : key2char( k, shift?, caps_lock?, num_lock?)
end
#--------------------------------------------------------------------------
# ● 打字中判定
#--------------------------------------------------------------------------
def self .typing ?
not type_char.empty ?
end
#--------------------------------------------------------------------------
# ● 根据字符或符号取得键名
#--------------------------------------------------------------------------
def self .get_key ( key)
if key.is_a ?( Symbol )
const_get( key) rescue NONE
elsif key.is_a ?( String )
char2key( key)
end
end
#--------------------------------------------------------------------------
# ● 将按键转化为字符
#--------------------------------------------------------------------------
def self .key2char ( code, shift = false , caps = false , num = true )
case code
when BACKSPACE..ENTER , ESCAPE, SPACE
code.chr
when D0..D9
shift ? ")!@#\$ %^&*(" [ code - D0] .chr : code.chr
when A..Z
shift ^ caps ? code.chr : ( code + 32 ) .chr
when NUM0..NUM9
num ? ( code - 48 ) .chr : ""
when MULTIPLY..DIVIDE
( num || code != DECIMAL) ? "*+,-./" [ code - 106 ] .chr : ""
when SEMICOLON..TILDE
";:=+,<-_.>/?`~" [ ( code - SEMICOLON << 1 ) + ( shift ? 1 : 0 ) ] .chr
when L_BRACE..QUOTE
"[{\\ |]}\' \" " [ ( code - L_BRACE << 1 ) + ( shift ? 1 : 0 ) ] .chr
else
""
end
end
#--------------------------------------------------------------------------
# ● 将字符转化为按键
#--------------------------------------------------------------------------
def self .char2key ( char)
return NONE if char.empty ?
case char[ 0 ]
when 8 ..13 , 27 , 32 , 48 ..57 , 65 ..90
char[ 0 ]
when 97 ..122
char[ 0 ] - 32
else
pindex = ")!@#\$ %^&*(" .index ( char[ 0 ] )
return D0 + pindex if pindex
pindex = ";:=+,<-_.>/?`~" .index ( char[ 0 ] )
return SEMICOLON + ( pindex >> 1 ) if pindex
pindex = "[{\\ |]}\' \" " .index ( char[ 0 ] )
return L_BRACE + ( pindex >> 1 ) if pindex
NONE
end
end
end
#==============================================================================
# ■ Input 模块的注入
#==============================================================================
module Input
class << self
unless method_defined?( :sailcat_sep_update )
alias sailcat_sep_update update
def update
sailcat_sep_update
Keyboard.update
end
end
end
end
#==============================================================================
# ■ SEP 全键盘处理 v1.0 by SailCat
#------------------------------------------------------------------------------
# 方法:本脚本插入Main之前使用
# 依赖:无
# 版本:v1.0 (Build 180110)
# 效果:
# 1. 全键盘按键响应
# 2. 注入Input模块的update处理
# 3. Lock键、Shift/Ctrl/Alt/Win键状态的响应
# 4. 获得输入的字符
# 配置:重复延迟和重复间隔速率
# 冲突:其他类似脚本
# 说明:
# 1. 调用全键盘方法为Keyboard.press?(键名常量、符号或字符)。
# 2. 上述press?也可替换为trigger?或repeat?,含义与Input中的同名方法相同。
# 3. 其他检测包括对于Lock键的状态,Shift/Ctrl/Alt/Win的状态检测等。
# 4. 使用Keyboard.type_char可以获得打字键入的字符。
#==============================================================================
#==============================================================================
# ■ SailCat's 插件公用
#==============================================================================
module SailCat
$sailcat_import ||= { }
#--------------------------------------------------------------------------
# ● 脚本配置区
#--------------------------------------------------------------------------
module Keyboard_Config
REPEAT_DELAY = 8 # 首次重复前的延迟值(帧)
REPEAT_SPEED = 2 # 每次重复按键的间隔(帧),越大越慢
#--------------------------------------------------------------------------
# ● 配置检查,请勿更改
#--------------------------------------------------------------------------
unless REPEAT_SPEED > 0
raise "重复按键的间隔不能低于1帧"
end
end
#--------------------------------------------------------------------------
# ● 植入
#--------------------------------------------------------------------------
$sailcat_import [ :Keyboard ] = 1.0
end
#==============================================================================
# ■ 全键盘处理核心
#==============================================================================
module Keyboard
include SailCat::Keyboard_Config
#--------------------------------------------------------------------------
# ● 常量
#--------------------------------------------------------------------------
NONE = 0
L_BUTTON, R_BUTTON, CANCEL, M_BUTTON, X_BUTTON1, X_BUTTON2 = *1 ..6
BACKSPACE, TAB, LINE_FEED, V_TAB, CLEAR, ENTER = *8 ..13
SHIFT_KEY, CONTROL_KEY, ALT_KEY, PAUSE_KEY = *16 ..19
CAPS_LOCK, KANA_MODE, JUNJA_MODE, DUMMY, FINAL_MODE, KANJI_MODE = *20 ..25
ESCAPE, IME_CONVERT, IME_NONCONVERT, IME_ACCEPT, IME_MODECHANGE = *27 ..31
SPACE, PAGEUP, PAGEDOWN, ENDKEY, HOME, LEFT, UP, RIGHT, DOWN = *32 ..40
SELECT , PRINT , EXECUTE, PRINTSCREEN, INSERT, DELETE, HELP = *41 ..47
D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 = *48 ..57
A, B, C, D, E, F, G, H, I, J, K, L, M = *65 ..77
N, O, P , Q, R, S, T, U, V, W, X, Y, Z = *78 ..90
LWIN, RWIN, APPS, SLEEP = 91 , 92 , 93 , 95
NUM0, NUM1, NUM2, NUM3, NUM4, NUM5, NUM6, NUM7, NUM8, NUM9 = *96 ..105
MULTIPLY, ADD, SEPARATOR, SUBTRACT, DECIMAL, DIVIDE = *106 ..111
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12 = *112 ..123
F13, F14, F15, F16, F17, F18, F19, F20, F21, F22, F23, F24 = *124 ..135
NUM_LOCK, SCROLL_LOCK = 144 , 145
L_SHIFT, R_SHIFT, L_CTRL, R_CTRL, L_ALT, R_ALT = *160 ..165
B_BACK, B_FORWARD, B_REFRESH, B_STOP, B_SEARCH, B_FAVOR, B_HOME = *166 ..172
VOL_MUTE, VOL_DOWN, VOL_UP = *173 ..175
MEDIA_NEXT, MEDIA_PREVIOUS, MEDIA_STOP, MEDIA_PLAYPAUSE = *176 ..179
LAUNCH_MAIL, SELECT_MEDIA, LAUNCH_APP1, LAUNCH_APP2 = *180 ..183
SEMICOLON, PLUS, COMMA, MINUS, PERIOD, QUESTION, TILDE = *186 ..192
L_BRACE, PIPE, R_BRACE, QUOTE, OEM8 = *219 ..223
BACKSLASH, PROCESS_KEY, PACKET = 226 , 229 , 231
ATTN, CRSEL, EXSEL, ERASE_EOF, PLAY, ZOOM, NONAME, PA1, OEM_CLEAR = *246 ..254
ANY_BUTTON = [ 1 , 2 , 4 , 5 , 6 ]
ANY_KEY = [ 8 ..13 , 27 , 32 ..57 , 65 ..90 , 96 ..135 , 186 ..192 , 219 ..223 ] .map do |x|
x.to_a
end .flatten
#--------------------------------------------------------------------------
# ● API
#--------------------------------------------------------------------------
GetAsyncKeyState = Win32API.new ( "user32" , "GetAsyncKeyState" , "i" , "i" )
GetKeyState = Win32API.new ( "user32" , "GetKeyState" , "i" , "i" )
#--------------------------------------------------------------------------
# ● 用于检测重复按键的标记器
#--------------------------------------------------------------------------
Flags = { }
#--------------------------------------------------------------------------
# ● 更新键盘输入,该方法每帧调用1次
#--------------------------------------------------------------------------
def self .update
Flags.each_key do |k|
GetAsyncKeyState.call ( k) & 32768 != 0 ? Flags[ k] += 1 : Flags.delete ( k)
end
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否现在被按下
#--------------------------------------------------------------------------
def self .press ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| press?( k) } if key.is_a ?( Array )
GetAsyncKeyState.call ( key) != 0 ? ( Flags[ key] ||= 0 ; true ) : false
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重新被按下
#--------------------------------------------------------------------------
def self .trigger ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| trigger?( k) } if key.is_a ?( Array )
Flags[ key] ? Flags[ key] == 0 : press?( key)
end
#--------------------------------------------------------------------------
# ● 判断对应的键是否重复被按下
#--------------------------------------------------------------------------
def self .repeat ?( key)
key = get_key( key) unless key.is_a ?( Numeric ) or key.is_a ?( Array )
return key.any ?{ |k| repeat?( k) } if key.is_a ?( Array )
Flags[ key] ? ( Flags[ key] >= REPEAT_DELAY and ( Flags[ key] - REPEAT_DELAY) %
REPEAT_SPEED == 0 ) : press?( key)
end
#--------------------------------------------------------------------------
# ● 键盘状态判断
#--------------------------------------------------------------------------
def self .lock ?( key) ; GetKeyState.call ( key) & 1 == 1 ; end
def self .caps_lock ?; lock?( CAPS_LOCK) ; end
def self .num_lock ?; lock?( NUM_LOCK) ; end
def self .scroll_lock ?; lock?( SCROLL_LOCK) ; end
#--------------------------------------------------------------------------
# ● 修饰键判断
#--------------------------------------------------------------------------
def self .shift ?; press?( [ SHIFT_KEY, L_SHIFT, R_SHIFT] ) ; end
def self .ctrl ?; press?( [ CONTROL_KEY, L_CTRL, R_CTRL] ) ; end
def self .alt ?; press?( [ ALT_KEY, L_ALT, R_ALT] ) ; end
def self .win ?; press?( [ L_WIN, R_WIN] ) ; end
#--------------------------------------------------------------------------
# ● 当前按下的键名
#--------------------------------------------------------------------------
def self .key_code
a = ANY_KEY.select { |key| repeat?( key) }
a.empty ? ? 0 : a[ 0 ]
end
#--------------------------------------------------------------------------
# ● 当前输入的字符
#--------------------------------------------------------------------------
def self .type_char
k = key_code
k == 0 ? "" : key2char( k, shift?, caps_lock?, num_lock?)
end
#--------------------------------------------------------------------------
# ● 打字中判定
#--------------------------------------------------------------------------
def self .typing ?
not type_char.empty ?
end
#--------------------------------------------------------------------------
# ● 根据字符或符号取得键名
#--------------------------------------------------------------------------
def self .get_key ( key)
if key.is_a ?( Symbol )
const_get( key) rescue NONE
elsif key.is_a ?( String )
char2key( key)
end
end
#--------------------------------------------------------------------------
# ● 将按键转化为字符
#--------------------------------------------------------------------------
def self .key2char ( code, shift = false , caps = false , num = true )
case code
when BACKSPACE..ENTER , ESCAPE, SPACE
code.chr
when D0..D9
shift ? ")!@#\$ %^&*(" [ code - D0] .chr : code.chr
when A..Z
shift ^ caps ? code.chr : ( code + 32 ) .chr
when NUM0..NUM9
num ? ( code - 48 ) .chr : ""
when MULTIPLY..DIVIDE
( num || code != DECIMAL) ? "*+,-./" [ code - 106 ] .chr : ""
when SEMICOLON..TILDE
";:=+,<-_.>/?`~" [ ( code - SEMICOLON << 1 ) + ( shift ? 1 : 0 ) ] .chr
when L_BRACE..QUOTE
"[{\\ |]}\' \" " [ ( code - L_BRACE << 1 ) + ( shift ? 1 : 0 ) ] .chr
else
""
end
end
#--------------------------------------------------------------------------
# ● 将字符转化为按键
#--------------------------------------------------------------------------
def self .char2key ( char)
return NONE if char.empty ?
case char[ 0 ]
when 8 ..13 , 27 , 32 , 48 ..57 , 65 ..90
char[ 0 ]
when 97 ..122
char[ 0 ] - 32
else
pindex = ")!@#\$ %^&*(" .index ( char[ 0 ] )
return D0 + pindex if pindex
pindex = ";:=+,<-_.>/?`~" .index ( char[ 0 ] )
return SEMICOLON + ( pindex >> 1 ) if pindex
pindex = "[{\\ |]}\' \" " .index ( char[ 0 ] )
return L_BRACE + ( pindex >> 1 ) if pindex
NONE
end
end
end
#==============================================================================
# ■ Input 模块的注入
#==============================================================================
module Input
class << self
unless method_defined?( :sailcat_sep_update )
alias sailcat_sep_update update
def update
sailcat_sep_update
Keyboard.update
end
end
end
end
评分
查看全部评分