#============================================================================== # ■ Input #------------------------------------------------------------------------------ #  キーの管理を行うモジュールです。 #============================================================================== module Input #-------------------------------------------------------------------------- # ● 懲りずに大量に定数宣言 #-------------------------------------------------------------------------- MOUSE_L = 1 MOUSE_R = 2 CANCEL = 3 MOUSE_S = 4 MOUSE_X1 = 5 MOUSE_X2 = 6 BACKSPACE = 8 TAB = 9 CLEAR = 12 ENTER = 13 SHIFT = 16 CTRL = 17 ALT = 18 PAUSE = 19 CAPSLOCK = 20 IME_KANA = 21 IME_KANZI = 25 ESC = 27 CONVERT = 28 NONCONVERT = 29 MODECHANGE = 31 SPACE = 32 PAGEUP = 33 PAGEDOWN = 34 VK_END = 35 HOME = 36 TRUE_LEFT = 37 TRUE_UP = 38 TRUE_RIGHT = 39 TRUE_DOWN = 40 SELECT = 41 PRINT = 42 EXECUTE = 43 PRINTSCREEN = 44 INSERT = 45 DELETE = 46 HELP = 47 ZERO = 48 ONE = 49 TWO = 50 THREE = 51 FOUR = 52 FIVE = 53 SIX = 54 SEVEN = 55 EIGHT = 56 NINE = 57 TRUE_A = 65 TRUE_B = 66 TRUE_C = 67 D = 68 E = 69 F = 70 G = 71 H = 72 I = 73 J = 74 K = 75 TRUE_L = 76 M = 77 N = 78 O = 79 P = 80 Q = 81 TRUE_R = 82 S = 83 T = 84 U = 85 V = 86 W = 87 TRUE_X = 88 TRUE_Y = 89 TRUE_Z = 90 WIN_L = 91 WIN_R = 92 APPS = 93 SLEEP = 95 TEN_ZERO = 96 TEN_ONE = 97 TEN_TWO = 98 TEN_THREE = 99 TEN_FOUR = 100 TEN_FIVE = 101 TEN_SIX = 102 TEN_SEVEN = 103 TEN_EIGHT = 104 TEN_NINE = 105 TEN_AST = 106 TEN_PRUS = 107 TEN_ENTER = 108 TEN_MINUS = 109 TEN_PERIOD = 110 TEN_SLASH = 111 F1 = 112 F2 = 113 F3 = 114 F4 = 115 F5 = 116 F6 = 117 F7 = 118 F8 = 119 F9 = 120 F10 = 121 F11 = 122 F12 = 123 F13 = 124 F14 = 125 F15 = 126 F16 = 127 F17 = 128 F18 = 129 F19 = 130 F20 = 131 F21 = 132 F22 = 133 F23 = 134 F24 = 135 NUMLOCK = 144 SCROCK = 145 SHIFT_L = 160 SHIFT_R = 161 CTRL_L = 162 CTRL_R = 163 ALT_L = 164 ALT_R = 165 B_BACK = 166 B_NEXT = 167 B_REFRESH = 168 B_STOP = 169 B_SEARCH = 170 B_FAVORITE = 171 B_HOME = 172 VOL_MUTE = 173 VOL_DOWN = 174 VOL_UP = 175 NEXT_TRACK = 176 PREV_TRACK = 177 MEDIA_STOP = 178 MEDIA_PLAY = 179 MALE = 180 MEDIA_SELECT = 181 APP1 = 182 APP2 = 183 COLON = 184 PRUS = 185 COMMA = 186 MINUS = 187 PERIOD = 188 SLASH = 189 AT_SIGN = 190 BREKET_L = 219 YEN = 220 BREKET_R = 221 ACCENT = 222 BACK_SLASH = 226 IME_PROCESS = 228 CAPSLOCK = 240 GETKEY = Win32API.new("user32", "GetKeyState", "i", "i") INPUTKEY = Win32API.new("user32", "keybd_event", %w(i v i i), "v") #-------------------------------------------------------------------------- # ● 大量カスタマイズポイント #-------------------------------------------------------------------------- REPERT_TIME = 4 # Input.repeatの判定をする間隔 A = [SHIFT, TRUE_Z] # Aに対応するキーの配列 B = [ESC, NUMLOCK, ZERO, TEN_ZERO, TRUE_X] # Bに対応するキーの配列 C = [SPACE, ENTER, TRUE_C] # Cに対応するキーの配列 L = [Q, PAGEUP] # Lに対応するキーの配列 R = [W, PAGEDOWN] # Rに対応するキーの配列 X = [TRUE_A] # Xに対応するキーの配列 Y = [S] # Yに対応するキーの配列 Z = [D] # Zに対応するキーの配列 LEFT = [TRUE_LEFT, TEN_FOUR] # 左に対応するキーの配列 UP = [TRUE_UP, TEN_EIGHT] # 上に対応するキーの配列 RIGHT = [TRUE_RIGHT, TEN_SIX] # 右に対応するキーの配列 DOWN = [TRUE_DOWN, TEN_TWO] # 下に対応するキーの配列 #-------------------------------------------------------------------------- # ● モジュール変数(である必要が無かったorz) #-------------------------------------------------------------------------- @@press = [] @@trigger = [] @@repeat = [] @@time = [] @@cons_press = [] #-------------------------------------------------------------------------- # ● 押されているか #-------------------------------------------------------------------------- def self.press?(key) # 定数が配列であった場合 if key.is_a?(Array) # 一つでも押されていればtrueを返す return @@press[code].include?(true) else # 押されていればtrueを返す return @@press[key] end end #-------------------------------------------------------------------------- # ● 新たに押されたか #-------------------------------------------------------------------------- def self.trigger?(key) # 定数が配列であった場合 if key.is_a?(Array) # 一つでも押されていればtrueを返す return @@trigger[code].include?(true) else # 押されていればtrueを返す return @@trigger[key] end end #-------------------------------------------------------------------------- # ● リピート #-------------------------------------------------------------------------- def self.repeat?(key) # 定数が配列であった場合 if key.is_a?(Array) # 一つでも押されていればtrueを返す return @@repeat[code].include?(true) else # 押されていればtrueを返す return @@repeat[key] end end #-------------------------------------------------------------------------- # ● 4方向確認 #-------------------------------------------------------------------------- def self.dir4 # 押されていないと0を返す if self.press?(DOWN) return 2 elsif self.press?(LEFT) return 4 elsif self.press?(RIGHT) return 6 elsif self.press?(UP) return 8 else return 0 end end #-------------------------------------------------------------------------- # ● 8方向確認 #-------------------------------------------------------------------------- def self.dir8 # 押されていないと0を返す if self.press?(DOWN) if self.press?(LEFT) return 1 elsif self.press?(RIGHT) return 3 else return 2 end end if self.press?(LEFT) return 4 end if self.press?(RIGHT) return 6 end if self.press?(UP) if self.press?(LEFT) return 7 elsif self.press?(RIGHT) return 9 else return 8 end end return dir end #-------------------------------------------------------------------------- # ● キーを押す #-------------------------------------------------------------------------- def self.press(key, type = 0) INPUTKEY.call(key, 0, type) end #-------------------------------------------------------------------------- # ● キーを押さない #-------------------------------------------------------------------------- def self.unpress(key, type = 0) INPUTKEY.call(key, 2, type) end #-------------------------------------------------------------------------- # ● キーを連打 #-------------------------------------------------------------------------- def self.cons_press(key, type = 0) @@cons_press[key] = [0, type] end #-------------------------------------------------------------------------- # ● キー連打解除 #-------------------------------------------------------------------------- def self.cons_press(key, type = 0) @@cons_press[key] = nil end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def self.update for code in 0..255 if @@cons_press[code] == nil @@cons_press[code] = [] end if @@cons_press[code][0] == 0 @@cons_press[code][0] = 1 INPUTKEY.call(code, 0, @@cons_press[code][1]) elsif @@cons_press[code][0] == 1 @@cons_press[code][0] = 0 INPUTKEY.call(code, 2, @@cons_press[code][1]) end if @@press[code] == true if (Graphics.frame_count % REPERT_TIME) == @@time[code] @@repeat[code] = true else @@repeat[code] = false end else @@repeat[code] = false end if GETKEY.call(code) == -128 or GETKEY.call(code) == -127 or GETKEY.call(code) == 65408 or GETKEY.call(code) == 65409 if @@press[code] == false @@trigger[code] = true else @@trigger[code] = false end @@press[code] = true if @@time[code] != 0 @@time[code] = Graphics.frame_count % REPERT_TIME end else @@press[code] = false @@trigger[code] = false @@time[code] = 0 end end end end #============================================================================== # ■ Interpreter #------------------------------------------------------------------------------ #  イベントコマンドを実行するインタプリタです。このクラスは Game_System クラ # スや Game_Event クラスの内部で使用されます。 #============================================================================== class Interpreter #-------------------------------------------------------------------------- # ● コマンドスキップ108 #-------------------------------------------------------------------------- def skip_108(name) # ループ loop do # 分岐名を持ったラベルまで飛ばす if @@list[@@index + 1] == nil print "ちゃんと条件分岐は終わらせろ!" return false end if @@list[@@index + 1].code == 119 and @@list[@@index+1].parameters[0] == name # 継続 return true end # インデックスを進める @@index += 1 end end #-------------------------------------------------------------------------- # ● 注釈イベントの実行 #-------------------------------------------------------------------------- if self.class.method_defined?("command_108") alias :base_command_108 :command_108 def command_108 # キーを押しっぱなしにする if @@parameter[0] =~ /\[(.+?)\]キーを押しっぱなしにする/ num = Input.constants # 定数に含まれていない場合 button = $1 code = "Input::" + button unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else # 定数が数字であった場合 if eval(code).is_a?(Numeric) Input.press(eval(code)) end end return true end # キーを押しっぱなしにしない if @@parameter[0] =~ /\[(.+?)\]キーを押しっぱなしにしない/ num = Input.constants_set # 定数に含まれていない場合 button = $1 code = "Input::" + button unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else # 定数が数字であった場合 if eval(code).is_a?(Numeric) Input.unpress(eval(code)) end end return true end # キーが押されているか if @@parameter[0] =~ /条件分岐\[(.+?)\] ?\[(.+?)\]ボタンが押されている/ num = Input.constants name = $1 button = $2 # 定数に含まれていなければ unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else code = "Input::" + "#{button}" # 指定したキーが押されていなければ unless Input.press?(eval(code)) return skip_108(name) end end return true end # キーが押されていないか if @@parameter[0] =~ /条件分岐\[(.+?)\] ?\[(.+?)\]ボタンが押されている/ num = Input.constants name = $1 button = $2 # 定数に含まれていなければ unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else code = "Input::" + "#{button}" # 指定したキーが押されていなければ if Input.press?(eval(code)) return skip_108(name) end end return true end # ループ キーが押されているか if @@parameter[0] =~ /ループ\[(.+?)\] ?\[(.+?)\]ボタンが押されている/ num = Input.constants name = $1 button = $2 # 定数に含まれていなければ unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else code = "Input::" + "#{button}" # 定数に含まれていなければ unless Input.press?(eval(code)) return skip_108(name) end end return true end # ループ キーが押されていないか if @@parameter[0] =~ /ループ\[(.+?)\] ?\[(.+?)\]ボタンが押されていない/ num = Input.constants name = $1 button = $2 # 定数に含まれていなければ unless num.include?(button) print "存在しないボタンを指定したので、この命令は無視されました。" else code = "Input::" + "#{button}" # 定数に含まれていなければ if Input.press?(eval(code)) return skip_108(name) end end return true end base_command_108 end end #-------------------------------------------------------------------------- # ● 条件分岐 #-------------------------------------------------------------------------- def command_111 # ローカル変数 result を初期化 result = false # 条件判定 case @@parameters[0] when 0 # スイッチ result = ($game_switches[@@parameters[1]] == (@@parameters[2] == 0)) when 1 # 変数 value1 = $game_variables[@@parameters[1]] if @@parameters[2] == 0 value2 = @@parameters[3] else value2 = $game_variables[@@parameters[3]] end case @@parameters[4] when 0 # と同値 result = (value1 == value2) when 1 # 以上 result = (value1 >= value2) when 2 # 以下 result = (value1 <= value2) when 3 # 超 result = (value1 > value2) when 4 # 未満 result = (value1 < value2) when 5 # 以外 result = (value1 != value2) end when 2 # セルフスイッチ if @@event_id > 0 key = [$game_map.map_id, @@event_id, @@parameters[1]] if @@parameters[2] == 0 result = ($game_self_switches[key] == true) else result = ($game_self_switches[key] != true) end end when 3 # タイマー if $game_system.timer_working sec = $game_system.timer / Graphics.frame_rate if @@parameters[2] == 0 result = (sec >= @@parameters[1]) else result = (sec <= @@parameters[1]) end end when 4 # アクター actor = $game_actors[@@parameters[1]] if actor != nil case @@parameters[2] when 0 # パーティにいる result = ($game_party.actors.include?(actor)) when 1 # 名前 result = (actor.name == @@parameters[3]) when 2 # スキル result = (actor.skill_learn?(@@parameters[3])) when 3 # 武器 result = (actor.weapon_id == @@parameters[3]) when 4 # 防具 result = (actor.armor1_id == @@parameters[3] or actor.armor2_id == @@parameters[3] or actor.armor3_id == @@parameters[3] or actor.armor4_id == @@parameters[3]) when 5 # ステート result = (actor.state?(@@parameters[3])) end end when 5 # エネミー enemy = $game_troop.enemies[@@parameters[1]] if enemy != nil case @@parameters[2] when 0 # 出現している result = (enemy.exist?) when 1 # ステート result = (enemy.state?(@@parameters[3])) end end when 6 # キャラクター character = get_character(@@parameters[1]) if character != nil result = (character.direction == @@parameters[2]) end when 7 # ゴールド if @@parameters[2] == 0 result = ($game_party.gold >= @@parameters[1]) else result = ($game_party.gold <= @@parameters[1]) end when 8 # アイテム result = ($game_party.item_number(@@parameters[1]) > 0) when 9 # 武器 result = ($game_party.weapon_number(@@parameters[1]) > 0) when 10 # 防具 result = ($game_party.armor_number(@@parameters[1]) > 0) when 11 # ボタン case @@parameters[1] when 2 str = "DOWN" when 4 str = "LEFT" when 6 str = "RIGHT" when 8 str = "UP" when 11 str = "A" when 12 str = "B" when 13 str = "C" when 14 str = "X" when 15 str = "Y" when 16 str = "Z" when 17 str = "L" when 18 str = "R" when 21 str = "SHIFT" when 22 str = "CTRL" when 23 str = "ALT" when 25 str = "F5" when 26 str = "F6" when 27 str = "F7" when 28 str = "F8" when 29 str = "F9" end result = (Input.press?(eval("Input::#{str}"))) when 12 # スクリプト result = eval(@@parameters[1]) end # 判定結果をハッシュに格納 @@branch[@@list[@@index].indent] = result # 判定結果が真だった場合 if @@branch[@@list[@@index].indent] == true # 分岐データを削除 @@branch.delete(@@list[@@index].indent) # 継続 return true end # 条件に該当しない場合 : コマンドスキップ return command_skip end #-------------------------------------------------------------------------- # ● ラベルジャンプ #-------------------------------------------------------------------------- def command_119 # ラベル名を取得 label_name = @@parameters[0] # 一時変数を初期化 temp_index = 0 # ループ loop do # 該当するラベルが見つからなかった場合 if temp_index >= @@list.size - 1 # 継続 return true end # このイベントコマンドが指定された名前のラベルの場合 if @@list[temp_index].code == 118 and @@list[temp_index].parameters[0] == label_name # インデックスを更新する @@index = temp_index # 継続 return true elsif @@list[temp_index].code == 108 or @@list[temp_index].code == 408 if @@list[temp_index].parameters[0] =~ /ループ\[(.+?)\] \[(\d+)\] ?([!=]=) ?\[(\d+)\]/ or @@list[temp_index].parameters[0] =~ /ループ\[(.+?)\] \[(.+?)\]ボタンが押されている/ or @@list[temp_index].parameters[0] =~ /ループ\[(.+?)\] \[(.+?)\]ボタンが押されていない/ # インデックスを更新する @@index = temp_index # 継続 return true end end # インデックスを進める temp_index += 1 end end end