=begin キーボード入力拡張 Author:: 半生 Version:: 0.0.1.0 Date:: 2014/01/17 Copyright:: Copyright (c) 2011-2014 半生 URL:: http://www.tktkgame.com RPGツクールXP/VX用 == 使い方 TKG::InputKB.press?('A') とか TKG::InputKB.press?('CTRL') 更新 2014/01/17 Ctrl,Shiftが環境によって?機能していなかったので修正。 ついでにCTRL、SHIFTは左右別々でも取得できるようにしました。 ・LCTRL,RCTRL,LSHIFT,RSHIFT =end module TKG module InputKB # 不明なキーコードエラー class UnknownCode < ::Exception; end # 仮想キーコード module KeyCode # いろいろ VK_BACK = 0x08 # Backspace VK_TAB = 0x09 # Tab VK_RETURN = 0x0D # Enter VK_SHIFT = 0x10 # Shift VK_CONTROL = 0x11 # Ctrl VK_MENU = 0x12 # Alt VK_PAUSE = 0x13 # Pause VK_CAPITAL = 0x14 # Caps Lock VK_SPACE = 0x20 # スペースキー VK_PRIOR = 0x21 # Page Up VK_NEXT = 0x22 # Page Down VK_END = 0x23 # End VK_HOME = 0x24 # Home # 矢印 VK_LEFT = 0x25 # 左 VK_UP = 0x26 # 上 VK_RIGHT = 0x27 # 右 VK_DOWN = 0x28 # 下 VK_SNAPSHOT = 0x2C # Print Screen VK_INSERT = 0x2D # Insert VK_DELETE = 0x2E # Delete VK_HELP = 0x2F # Help # 数字 VK_0 = 0x30 VK_1 = 0x31 VK_2 = 0x32 VK_3 = 0x33 VK_4 = 0x34 VK_5 = 0x35 VK_6 = 0x36 VK_7 = 0x37 VK_8 = 0x38 VK_9 = 0x39 # アルファベット VK_A = 0x41 VK_B = 0x42 VK_C = 0x43 VK_D = 0x44 VK_E = 0x45 VK_F = 0x46 VK_G = 0x47 VK_H = 0x48 VK_I = 0x49 VK_J = 0x4A VK_K = 0x4B VK_L = 0x4C VK_M = 0x4D VK_N = 0x4E VK_O = 0x4F VK_P = 0x50 VK_Q = 0x51 VK_R = 0x52 VK_S = 0x53 VK_T = 0x54 VK_U = 0x55 VK_V = 0x56 VK_W = 0x57 VK_X = 0x58 VK_Y = 0x59 VK_Z = 0x5A # NUMPAD VK_NUM0 = 0x60 VK_NUM1 = 0x61 VK_NUM2 = 0x62 VK_NUM3 = 0x63 VK_NUM4 = 0x64 VK_NUM5 = 0x65 VK_NUM6 = 0x66 VK_NUM7 = 0x67 VK_NUM8 = 0x68 VK_NUM9 = 0x69 # ファンクション VK_F1 = 0x70 VK_F2 = 0x71 VK_F3 = 0x72 VK_F4 = 0x73 VK_F5 = 0x74 VK_F6 = 0x75 VK_F7 = 0x76 VK_F8 = 0x77 VK_F9 = 0x78 VK_F10 = 0x79 VK_F11 = 0x7a VK_F12 = 0x7b # 他 VK_LSHIFT = 0xA0 VK_RSHIFT = 0xA1 VK_LCONTROL = 0xA2 VK_RCONTROL = 0xA3 @@str_code = { "BS" => VK_BACK, "TAB" => VK_TAB, "LSHIFT" => VK_LSHIFT, "RSHIFT" => VK_RSHIFT, "SHIFT" => [VK_SHIFT,VK_LSHIFT,VK_RSHIFT], "LCTRL" => VK_LCONTROL, "RCTRL" => VK_RCONTROL, "CTRL" => [VK_CONTROL,VK_LCONTROL,VK_RCONTROL], "ALT" => VK_MENU, "PAUSE" => VK_PAUSE, "SPACE" => VK_SPACE, "ENTER" => VK_RETURN, "RETURN" => VK_RETURN, "END" => VK_END, "HOME" => VK_HOME, "CAPS" => VK_CAPITAL, "PAGEUP" => VK_PRIOR, "PAGEDOWN" => VK_NEXT, "PRINT" => VK_SNAPSHOT, "INSERT" => VK_INSERT, "DELETE" => VK_DELETE, "HELP" => VK_HELP, } ('A'..'Z').each do |key| @@str_code[key] = const_get("VK_#{key}") end ('0'..'9').each do |key| @@str_code[key] = const_get("VK_#{key}") @@str_code["NUM#{key}"] = const_get("VK_NUM#{key}") end 12.times do |i| key = "F#{(i+1).to_s}" @@str_code[key] = const_get("VK_#{key}") end def self.str2code(str) str = str.upcase if @@str_code.include?(str) return @@str_code[str] else return -1 end end end include KeyCode # キー状態取得API # 引数 :仮想キーコード # 戻り値:現在押されている場合はマイナス(最上位ビットが1) @@get_key_state = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i') @@key_states = {} class << self # 更新処理 # trigger?を使う場合は毎フレーム呼び出す必要あり def update @@key_states.each_key do |kc| @@key_states[kc] = @@get_key_state.call(kc) end end # 監視対象等をリセット def reset @@key_states.clear end # キーの監視を予約 def set_key_monitor(key) key = KeyCode::str2code(key) if key.is_a?(String) if key.is_a?(Array) key.each { |k| self.set_key_monitor(k) } return end raise UnknownCode if key > 255 or key < 0 unless @@key_states.key?(key) @@key_states[key] = @@get_key_state.call(key) end end # キーの監視を解除 def remove_key_monitor(key) key = KeyCode::str2code(key) if key.is_a?(String) if key.is_a?(Array) key.each { |k| self.remove_key_monitor(k) } return end @@key_states.delete(key) end # キーが押されているか def press?(key) key = KeyCode::str2code(key) if key.is_a?(String) if key.is_a?(Array) key.each do |k| return true if self::press?(k) end return false end raise UnknownCode if key > 255 or key < 0 if @@key_states.key?(key) return @@key_states[key] < 0 ? true : false else return @@get_key_state.call(key) < 0 ? true : false end end # 前回の呼び出し以降に押されたかどうか # 監視対象に入っていないキーの場合最初の呼び出しはfalse def trigger?(key) key = KeyCode::str2code(key) if key.is_a?(String) if key.is_a?(Array) key.each do |k| return true if self::trigger?(k) end return false end raise UnknownCode if key > 255 or key < 0 # 監視対象に入ってない場合は監視対象に unless @@key_states.key?(key) set_key_monitor(key) end return (@@key_states[key] & 0x01) > 0 ? true : false end # 押しっぱなし判定 def repeat?(key) key = KeyCode::str2code(key) if key.is_a?(String) if key.is_a?(Array) key.each do |k| return true if self::repeat?(k) end return false end press?(key) && trigger?(key) end end end end class << Input unless method_defined?(:_tkg_inputkb__update) alias _tkg_inputkb__update update end #-- # ::Inputの更新タイミング時一緒に更新 #++ def update _tkg_inputkb__update TKG::InputKB.update end end