#============================================================================== # ** Glitchfinder's Key Input Module # Version 1.30 #------------------------------------------------------------------------------ # [RPG Maker XP] [RPG Maker VX] [RPG Maker VX Ace] #------------------------------------------------------------------------------ # This script helps scripters to use the full range of keys on any keyboard, # without being limited by the default Input Module. #============================================================================== # * Version History #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Version 1.00 ------------------------------------------------- (2010-03-18) # - Initial version # - Author: Glitchfinder # Version 1.10 ------------------------------------------------ (2010-08-20) # - Added the Keys.toggle? method # - Added the Keys.capslock? method # - Added the Keys.numlock? method # - Added the Keys.scroll? method # - Added the Keys.character_press method # - Added the Keys.character_trigger method # - Added the Keys.character_repeat method # - Added the Keys.get_character method # - Added the ANYKEY key constant # - Streamlined the script # - Patched various errors # - Author: Glitchfinder # Version 1.20 ------------------------------------------------ (2011-03-17) # - Added the Keys.array_press? method # - Added the Keys.array_trigger? method # - Added the Keys.array_repeat? method # - Added the Keys.array_release? method # - Added the Keys.array_toggle? method # - Modified the Keys.press? method for better error hendling # - Modified the Keys.trigger? method for better error hendling # - Modified the Keys.repeat? method for better error hendling # - Modified the Keys.release? method for better error hendling # - Modified the Keys.toggle? method for better error hendling # - Author: Glitchfinder # Version 1.30 ------------------------------------------------ (2014-02-07) # - Added the Keys.validate_key? method # - Modified the Keys.array_press? method for efficiency # - Modified the Keys.array_trigger? method for efficiency # - Modified the Keys.array_repeat? method for efficiency # - Modified the Keys.array_release? method for efficiency # - Modified the Keys.array_toggle? method for efficiency # - Modified the Keys.press? method to reduce unnecessary code # - Modified the Keys.trigger? method to reduce unnecessary code # - Modified the Keys.repeat? method to reduce unnecessary code # - Modified the Keys.release? method to reduce unnecessary code # - Modified the Keys.toggle? method to reduce unnecessary code # - Changed the license to be more open # - Author: Glitchfinder #============================================================================== # * Instructions #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Place this script above Main, and below the default scripts. (I realize this # is obvious to most, but some people don't get it.) # # This module is automatically updated by the default Input module, which # means that the only time you need to call the update method is in a scene # that does not update the default Input module. # # This module does not break the functionality of the default Input module. # # If you wish to read keys from a gamepad, you must still use the default # input module to do so. # # To use this module, simply use one of the four methods (press?(key), # trigger?(key), repeat?(key), or release?(key)), where key is the index of # the key you want to check. Key may also be used as Keys::KEYNAME. For a list # of acceptable key names, look below the header. # # There is a key named ANYKEY. This key can be used like any other key, with # the exception that, instead of corresponding to any one key, it reacts to # them all. If you use it, and any other key would cause the same method to # return true, then the ANYKEY will also return true. #============================================================================== # * Method List #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # Keys.update # Updates keyboard input. Calls to this method are not necessary unless the # default Input module is not being updated. # # Keys.press?(key) # Determines whether the button determined by key is currently being # pressed. If the button is being pressed, returns true. If not, returns # false. # # Keys.trigger?(key) # Determines whether the button determined by key is being pressed again. # "Pressed again" is seen as time having passed between the button being not # pressed and being pressed. If the button is being pressed, returns true. # If not, returns false. # # Keys.repeat?(key) # Determines whether the button determined by key is being pressed again. # Unlike trigger?(), this takes into account the repeat input of a button # being held down continuously. If the button is being pressed, returns # true. If not, returns false. # # Keys.release?(key) # Determines whether the button determined by key has just been released. If # the button has been released, returns true. If not, returns false. # # Keys.toggle?(key) # Determines whether the button determined by key has been toggled. This # functions like Caps Lock, Number Lock, and Scroll Lock, only for all keys. # # Keys.array_press?(keys) # Functions in the same manner as Keys.press?(), only it takes an array of # keys as input. # # Keys.array_trigger?(keys) # Functions in the same manner as Keys.trigger?(), only it takes an array of # keys as input. # # Keys.array_repeat?(keys) # Functions in the same manner as Keys.repeat?(), only it takes an array of # keys as input. # # Keys.array_release?(keys) # Functions in the same manner as Keys.release?(), only it takes an array of # keys as input. # # Keys.array_toggle?(keys) # Functions in the same manner as Keys.toggle?(), only it takes an array of # keys as input. # # Keys.capslock? # Determines whether the caps lock key is toggled on. This will always # return true when the corresponding keyboard light is lit, and false when # it is not. # # Keys.numlock? # Determines whether the number lock key is toggled on. This will always # return true when the corresponding keyboard light is lit, and false when # it is not. # # Keys.scroll? # Determines whether the scroll lock key is toggled on. This will always # return true when the corresponding keyboard light is lit, and false when # it is not. # # Keys.character_press # Returns the currently pressed key, if it would generate text input. If no # such key would register as pressed, it returns an empty string. # # Keys.character_trigger # Returns the currently triggered key, if it would generate text input. If # no such key would register as triggered, it returns an empty string. # # Keys.character_repeat # Returns the currently repeated key, if it would generate text input. If no # such key would register as repeated, it returns an empty string. # # Keys.get_character(key, scan_code) # Returns the character corresponding to the given key. If no character # is recognized by the system, it returns false instead. This method is # intended for internal use. # # Keys.validate_key(key) # Checks the validity of a key. If a key variable can be used by this # module, it will return true. Otherwise, it will return false. #============================================================================== # * Known Issues #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # This script has trouble with certain foreign language keyboards, where dead # keys are shift sensitive. Dead keys are used to insert diacritical marks # such as an accent. However, the correct character can be generated with # creative use of shift and caps lock. #============================================================================== # * Glitchfinder's Advice #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # This script is meant for people with a medium or advanced level of scripting # knowledge and ability, or for those using scripts that require this module. #============================================================================== # * License #^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # This script is licensed under the MIT License: # # Copyright (c) 2010-2014 Sean Porter (Glitchfinder) <[email protected]> # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. #============================================================================== #============================================================================== # ** Keys #------------------------------------------------------------------------------ # This module performs key input processing #============================================================================== module Keys #-------------------------------------------------------------------------- # * Miscellaneous Keys #-------------------------------------------------------------------------- CANCEL = 0x03 # Control-Break Processing BACKSPACE = 0x08 # Backspace Key TAB = 0x09 # Tab Key CLEAR = 0x0C # Clear Key RETURN = 0x0D # Enter Key SHIFT = 0x10 # Shift Key CONTROL = 0x11 # Ctrl Key MENU = 0x12 # Alt Key PAUSE = 0x13 # Pause Key ESCAPE = 0x1B # Esc Key CONVERT = 0x1C # IME Convert Key NONCONVERT = 0x1D # IME Nonconvert Key ACCEPT = 0x1E # IME Accept Key SPACE = 0x20 # Space Bar Key (Space, usually blank) PRIOR = 0x21 # Page Up Key NEXT = 0x22 # Page Down Key ENDS = 0x23 # End Key HOME = 0x24 # Home Key LEFT = 0x25 # Left Arrow Key UP = 0x26 # Up Arrow Key RIGHT = 0x27 # Right Arrow Key DOWN = 0x28 # Down Arrow Key SELECT = 0x29 # Select Key PRINT = 0x2A # Print Key EXECUTE = 0x2B # Execute Key SNAPSHOT = 0x2C # Print Screen Key DELETE = 0x2E # Delete Key HELP = 0x2F # Help Key LSHIFT = 0xA0 # Left Shift Key RSHIFT = 0xA1 # Right Shift Key LCONTROL = 0xA2 # Left Control Key (Ctrl) RCONTROL = 0xA3 # Right Control Key (Ctrl) LMENU = 0xA4 # Left Menu Key (Alt) RMENU = 0xA5 # Right Menu Key (Alt) PACKET = 0xE7 # Used to Pass Unicode Characters as Keystrokes #-------------------------------------------------------------------------- # * Number Keys #-------------------------------------------------------------------------- N0 = 0x30 # 0 Key N1 = 0x31 # 1 Key N2 = 0x32 # 2 Key N3 = 0x33 # 3 Key N4 = 0x34 # 4 Key N5 = 0x35 # 5 Key N6 = 0x36 # 6 Key N7 = 0x37 # 7 Key N8 = 0x38 # 8 Key N9 = 0x39 # 9 Key #-------------------------------------------------------------------------- # * Letter Keys #-------------------------------------------------------------------------- A = 0x41 # A Key B = 0x42 # B Key C = 0x43 # C Key D = 0x44 # D Key E = 0x45 # E Key F = 0x46 # F Key G = 0x47 # G Key H = 0x48 # H Key I = 0x49 # I Key J = 0x4A # J Key K = 0x4B # K Key L = 0x4C # L Key M = 0x4D # M Key N = 0x4E # N Key O = 0x4F # O Key P = 0x50 # P Key Q = 0x51 # Q Key R = 0x52 # R Key S = 0x53 # S Key T = 0x54 # T Key U = 0x55 # U Key V = 0x56 # V Key W = 0x57 # W Key X = 0x58 # X Key Y = 0x59 # Y Key Z = 0x5A # Z Key #-------------------------------------------------------------------------- # * Windows Keys #-------------------------------------------------------------------------- LWIN = 0x5B # Left Windows Key (Natural keyboard) RWIN = 0x5C # Right Windows Key (Natural Keyboard) APPS = 0x5D # Applications Key (Natural keyboard) SLEEP = 0x5F # Computer Sleep Key BROWSER_BACK = 0xA6 # Browser Back Key BROWSER_FORWARD = 0xA7 # Browser Forward Key BROWSER_REFRESH = 0xA8 # Browser Refresh Key BROWSER_STOP = 0xA9 # Browser Stop Key BROWSER_SEARCH = 0xAA # Browser Search Key BROWSER_FAVORITES = 0xAB # Browser Favorites Key BROWSER_HOME = 0xAC # Browser Start and Home Key VOLUME_MUTE = 0xAD # Volume Mute Key VOLUME_DOWN = 0xAE # Volume Down Key VOLUME_UP = 0xAF # Volume Up Key MEDIA_NEXT_TRACK = 0xB0 # Next Track Key MEDIA_PREV_TRACK = 0xB1 # Previous Track Key MEDIA_STOP = 0xB2 # Stop Media Key MEDIA_PLAY_PAUSE = 0xB3 # Play/Pause Media Key LAUNCH_MAIL = 0xB4 # Start Mail Key LAUNCH_MEDIA_SELECT = 0xB5 # Select Media Key LAUNCH_APP1 = 0xB6 # Start Application 1 Key LAUNCH_APP2 = 0xB7 # Start Application 2 Key PROCESSKEY = 0xE5 # IME Process Key ATTN = 0xF6 # Attn Key CRSEL = 0xF7 # CrSel Key EXSEL = 0xF8 # ExSel Key EREOF = 0xF9 # Erase EOF Key PLAY = 0xFA # Play Key ZOOM = 0xFB # Zoom Key PA1 = 0xFD # PA1 Key #-------------------------------------------------------------------------- # * Number Pad Keys #-------------------------------------------------------------------------- NUMPAD0 = 0x60 # Numeric Keypad 0 Key NUMPAD1 = 0x61 # Numeric Keypad 1 Key NUMPAD2 = 0x62 # Numeric Keypad 2 Key NUMPAD3 = 0x63 # Numeric Keypad 3 Key NUMPAD4 = 0x64 # Numeric Keypad 4 Key NUMPAD5 = 0x65 # Numeric Keypad 5 Key NUMPAD6 = 0x66 # Numeric Keypad 6 Key NUMPAD7 = 0x67 # Numeric Keypad 7 Key NUMPAD8 = 0x68 # Numeric Keypad 8 Key NUMPAD9 = 0x69 # Numeric Keypad 9 Key MULTIPLY = 0x6A # Multiply Key (*) ADD = 0x6B # Add Key (+) SEPARATOR = 0x6C # Separator Key SUBTRACT = 0x6D # Subtract Key (-) DECIMAL = 0x6E # Decimal Key (.) DIVIDE = 0x6F # Divide Key (/) #-------------------------------------------------------------------------- # * Function Keys #-------------------------------------------------------------------------- F1 = 0x70 # F1 Key F2 = 0x71 # F2 Key F3 = 0x72 # F3 Key F4 = 0x73 # F4 Key F5 = 0x74 # F5 Key F6 = 0x75 # F6 Key F7 = 0x76 # F7 Key F8 = 0x77 # F8 Key F9 = 0x78 # F9 Key F10 = 0x79 # F10 Key F11 = 0x7A # F11 Key F12 = 0x7B # F12 Key F13 = 0x7C # F13 Key F14 = 0x7D # F14 Key F15 = 0x7E # F15 Key F16 = 0x7F # F16 Key F17 = 0x80 # F17 Key F18 = 0x81 # F18 Key F19 = 0x82 # F19 Key F20 = 0x83 # F20 Key F21 = 0x84 # F21 Key F22 = 0x85 # F22 Key F23 = 0x86 # F23 Key F24 = 0x87 # F24 Key #-------------------------------------------------------------------------- # * Toggle Keys #-------------------------------------------------------------------------- CAPITAL = 0x14 # Caps Lock Key KANA = 0x15 # IME Kana Mode Key HANGUL = 0x15 # IME Hangul Mode Key JUNJA = 0x17 # IME Junja Mode Key FINAL = 0x18 # IME Final Mode Key HANJA = 0x19 # IME Hanja Mode Key KANJI = 0x19 # IME Kanji Mode Key MODECHANGE = 0x1F # IME Mode Change Request Key INSERT = 0x2D # Insert Key NUMLOCK = 0x90 # Num Lock Key SCROLL = 0x91 # Scroll Lock Key #-------------------------------------------------------------------------- # * OEM Keys (Vary by keyboard) #-------------------------------------------------------------------------- OEM_1 = 0xBA # Misc Characters (; : in USA 101/102 Keyboards) OEM_PLUS = 0xBB # + = Key OEM_COMMA = 0xBC # , < Key OEM_MINUS = 0xBD # - _ Key OEM_PERIOD = 0xBE # . > Key OEM_2 = 0xBF # Misc Characters (/ ? in USA 101/102 Keyboards) OEM_3 = 0xC0 # Misc Characters (` ~ in USA 101/102 Keyboards) OEM_4 = 0xDB # Misc Characters ([ { in USA 101/102 Keyboards) OEM_5 = 0xDC # Misc Characters (\ | in USA 101/102 Keyboards) OEM_6 = 0xDD # Misc Characters (] } in USA 101/102 Keyboards) OEM_7 = 0xDE # Misc Characters (' " in USA 101/102 Keyboards) OEM_8 = 0xDF # Misc Characters (Varies by Keyboard) OEM_9 = 0xE1 # OEM Specific OEM_10 = 0x92 # OEM Specific OEM_11 = 0x93 # OEM Specific OEM_12 = 0x94 # OEM Specific OEM_13 = 0x95 # OEM Specific OEM_14 = 0x96 # OEM Specific OEM_15 = 0xE3 # OEM Specific OEM_16 = 0xE4 # OEM Specific OEM_17 = 0xE6 # OEM Specific OEM_18 = 0xE9 # OEM Specific OEM_19 = 0xEA # OEM Specific OEM_20 = 0xEB # OEM Specific OEM_21 = 0xEC # OEM Specific OEM_22 = 0xED # OEM Specific OEM_23 = 0xEE # OEM Specific OEM_24 = 0xEF # OEM Specific OEM_25 = 0xF1 # OEM Specific OEM_26 = 0xF2 # OEM Specific OEM_27 = 0xF3 # OEM Specific OEM_28 = 0xF4 # OEM Specific OEM_29 = 0xF5 # OEM Specific OEM_102 = 0xE2 # Angle Bracket or Backslash on RT-102 Keyboards OEM_CLEAR = 0xFE # Clear Key #-------------------------------------------------------------------------- # * Special Keys #-------------------------------------------------------------------------- ANYKEY = 0x100 # Any Key #-------------------------------------------------------------------------- # * Declare Module Variables #-------------------------------------------------------------------------- begin # Create strings for unpacking input @unpack_string = 'B' * 256 @toggle_unpack_string = 'b' * 256 # Generate blank input arrays @last_array = '0' * 256 @press = Array.new(256, false) # Key currently pressed @trigger = Array.new(256, false) # Key initially pressed @repeat = Array.new(256, false) # Key being held @release = Array.new(256, false) # Key being released @toggle = Array.new(256, false) # Key currently toggled # Generate blank counter array @repeat_counter = Array.new(256, 0) # Declare keyboard API @getKeyboardState = Win32API.new('user32.dll', 'GetKeyboardState', 'P', 'V') @getAsyncKeyState = Win32API.new('user32.dll', 'GetAsyncKeyState', 'I', 'I') @getKeyState = Win32API.new('user32.dll', 'GetKeyState', 'I', 'I') @getKeyboardLayoutName = Win32API.new('user32.dll', 'GetKeyboardLayoutName', 'P', 'I') @loadKeyboardLayout = Win32API.new('user32.dll', 'LoadKeyboardLayout', 'PI', 'I') @mapVirtualKeyEx = Win32API.new('user32.dll', 'MapVirtualKeyEx', 'III', 'I') @toUnicodeEx = Win32API.new('user32.dll', 'ToUnicodeEx', 'IIPPIII', 'I') # Call current keyboard state @getKeyboardState.call(@last_array) # Set previous keyboard state @last_array = @last_array.unpack(@unpack_string) # Set a blank keyboard state @keyboard_state = '0'*256 # Set array to input character list @input_characters = [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, OEM_MINUS, OEM_PLUS, OEM_COMMA, OEM_PERIOD, OEM_1, OEM_2, OEM_3, OEM_4, OEM_5, OEM_6, OEM_7, OEM_8, OEM_9, OEM_10, OEM_11, OEM_12, OEM_13, OEM_14, OEM_15, OEM_16, OEM_17, OEM_18, OEM_19, OEM_20, OEM_21, OEM_22, OEM_23, OEM_24, OEM_25, OEM_26, OEM_27, OEM_28, OEM_29, OEM_102, NUMPAD0, NUMPAD1, NUMPAD2, NUMPAD3, NUMPAD4, NUMPAD5, NUMPAD6, NUMPAD7, NUMPAD8, NUMPAD9, DECIMAL, MULTIPLY, ADD, SEPARATOR, SUBTRACT, DIVIDE, SPACE] # Create a keyboard layout buffer layout_name = '0' * 8 # Get the keyboard name success = @getKeyboardLayoutName.call(layout_name) # Set the layout to US 101 if no name was obtained layout_name = '00000409' if success == 0 # Save the keyboard layout @layout = @loadKeyboardLayout.call(layout_name, 0x00000001) # Create an empty array to store mapped virtual keys @mapped_keys = [] # Iterate through the input character list for key in @input_characters # Insert the mapped virtual key into the array @mapped_keys.push(@mapVirtualKeyEx.call(key, 0, @layout)) end # create blank input array @keyboard_state = '0'*256 # Call current keyboard state @getKeyboardState.call(@keyboard_state) # Create an array to detect dead keys @dead_keys = [] # Iterate through the input character array for key in 0...256 # Find the key's current scan code scan_code = @mapVirtualKeyEx.call(key, 0, @layout) # Skip if there is no scan code for the current layout next if scan_code == 0 # Create a character buffer buffer = '0' * 10 # Test the key dead_key = @toUnicodeEx.call(key, scan_code, @keyboard_state, buffer, 5, 0, @layout) # if the key is a dead key if dead_key == -1 # Add the key to the dead key array @dead_keys.push(key) # Create a character buffer buffer = '0' * 10 # Clear the input queue dead_key = @toUnicodeEx.call(@input_characters[-1], @mapped_keys[-1], @keyboard_state, buffer, 5, 0, @layout) end end # Set the dead keys to off @dead_key_on = false end #-------------------------------------------------------------------------- # * Frame Update #-------------------------------------------------------------------------- def self.update # Clear input arrays @trigger = Array.new(256, false) @repeat = Array.new(256, false) @release = Array.new(256, false) # create blank input array @keyboard_state = '0' * 256 # Call current keyboard state @getKeyboardState.call(@keyboard_state) # unpack toggle array toggle = @keyboard_state.unpack(@toggle_unpack_string) # Unpack key array array = @keyboard_state.unpack(@unpack_string) # Cycle through all keys for i in 0...array.size # Set the current key state @press[i] = (array[i].to_i != 0) # Set the current toggle unpack state @toggle[i] = (toggle[i].to_i != 0) # If the current key state does not match the previous state if array[i] != @last_array[i] # If the repeat counter is at 0 if @repeat_counter[i] <= 0 && @press[i] # Set the key to repeat @repeat[i] = true # Set the repeat counter to 15 frames @repeat_counter[i] = 15 end # If the key is not being pressed if !@press[i] # Set the key to released @release[i] = true # If the key is being pressed else # Set the key to triggered @trigger[i] = true end # If the key state is the same else # If the repeat counter is greater than 0 and the key is pressed if @repeat_counter[i] > 0 && @press[i] # Cycle the repeat counter down one frame @repeat_counter[i] -= 1 # If the repeat counter is 0 or less and the key is pressed elsif @repeat_counter[i] <= 0 && @press[i] # Set the key to repeat @repeat[i] = true # Set the repeat counter to 15 frames @repeat_counter[i] = 3 # If the repeat counter does not equal 0 elsif @repeat_counter[i] != 0 && !@press[i] # Set the repeat counter to 0 @repeat_counter[i] = 0 end end end # Set the previous keyboard state @last_array = array end #-------------------------------------------------------------------------- # * Get Key Pressed State # key : key index #-------------------------------------------------------------------------- def self.press?(key) # Return the array state if key is an array return array_press?(key) if (Array == key.class) # Return false if key is invalid return false if !validate_key(key) # Return for any key return @press.include?(true) if key == 0x100 # Return key pressed state return @press[key] end #-------------------------------------------------------------------------- # * Get Key Triggered State # key : key index #-------------------------------------------------------------------------- def self.trigger?(key) # Return the array state if key is an array return array_trigger?(key) if (Array == key.class) # Return false if key is invalid return false if !validate_key(key) # Return for any key return @trigger.include?(true) if key == 0x100 # Return key triggered state return @trigger[key] end #-------------------------------------------------------------------------- # * Get Key Repeated State # key : key index #-------------------------------------------------------------------------- def self.repeat?(key) # Return the array state if key is an array return array_repeat?(key) if (Array == key.class) # Return false if key is invalid return false if !validate_key(key) # Return for any key return @repeat.include?(true) if key == 0x100 # Return key repeated state return @repeat[key] end #-------------------------------------------------------------------------- # * Get Key Released State # key : key index #-------------------------------------------------------------------------- def self.release?(key) # Return the array state if key is an array return array_release?(key) if (Array == key.class) # Return false if key is invalid return false if !validate_key(key) # Return for any key return @release.include?(true) if key == 0x100 # Return key released state return @release[key] end #-------------------------------------------------------------------------- # * Get Key Toggled State # key : key index #-------------------------------------------------------------------------- def self.toggle?(key) # Return the array state if key is an array return array_toggle?(key) if (Array == key.class) # Return false if key is invalid return false if !validate_key(key) # Return for any key return @toggle.include?(true) if key == 0x100 # Return key toggled state return @toggle[key] end #-------------------------------------------------------------------------- # * Get Key Pressed State (array) # keys : array of key indices #-------------------------------------------------------------------------- def self.array_press?(keys) # Return as a key if the input is not an array return press?(keys) if (Array != keys.class) # Create a temporary array to store key states states = [false] # Iterate through the keys array for key in keys # Add the key state to the array states << press?(key) end # Return true if any of the keys were pressed return states.include?(true) end #-------------------------------------------------------------------------- # * Get Key Triggered State (array) # keys : array of key indices #-------------------------------------------------------------------------- def self.array_trigger?(keys) # Return as a key if the input is not an array return trigger?(keys.to_i) if (Array != keys.class) # Create a temporary array to store key states states = [false] # Iterate through the keys array for key in keys # Add the key state to the array states << trigger?(key) end # Return true if any of the keys were pressed return states.include?(true) end #-------------------------------------------------------------------------- # * Get Key Repeated State (array) # keys : array of key indices #-------------------------------------------------------------------------- def self.array_repeat?(keys) # Return as a key if the input is not an array return repeat?(keys.to_i) if (Array != keys.class) # Create a temporary array to store key states states = [false] # Iterate through the keys array for key in keys # Add the key state to the array states << repeat?(key) end # Return true if any of the keys were pressed return states.include?(true) end #-------------------------------------------------------------------------- # * Get Key Released State (array) # keys : array of key indices #-------------------------------------------------------------------------- def self.array_release?(keys) # Return as a key if the input is not an array return release?(keys.to_i) if (Array != keys.class) # Create a temporary array to store key states states = [false] # Iterate through the keys array for key in keys # Add the key state to the array states << release?(key) end # Return true if any of the keys were pressed return states.include?(true) end #-------------------------------------------------------------------------- # * Get Key Toggled State (array) # keys : array of key indices #-------------------------------------------------------------------------- def self.array_toggle?(keys) # Return as a key if the input is not an array return toggle?(keys.to_i) if (Array != keys.class) # Create a temporary array to store key states states = [false] # Iterate through the keys array for key in keys # Add the key state to the array states << toggle?(key) end # Return true if any of the keys were pressed return states.include?(true) end #-------------------------------------------------------------------------- # * Get Caps Lock State #-------------------------------------------------------------------------- def self.capslock? # Return the current toggle state of Caps Lock return @toggle[CAPITAL] end #-------------------------------------------------------------------------- # * Get Number Lock State #-------------------------------------------------------------------------- def self.numlock? # Return the current toggle state of Num Lock return @toggle[NUMLOCK] end #-------------------------------------------------------------------------- # * Get Scroll Lock State #-------------------------------------------------------------------------- def self.scroll? # Return the current toggle state of Scroll Lock return @toggle[SCROLL] end #-------------------------------------------------------------------------- # * Return Current Key Character Pressed #-------------------------------------------------------------------------- def self.character_press # Iterate through the list of input characters for i in 0...@input_characters.size # Set a temporary variable to the value of the current key key = @input_characters[i] # Skip if the character is not currently pressed next unless self.press?(key) # Get the current key's scan code scan_code = @mapped_keys[i] # Get the specified character character = get_character(key, scan_code) # Skip if there was no translation for the character next if !character || character == -1 # Return the translated character return character end # Return blank if no characters were returned return "" end #-------------------------------------------------------------------------- # * Return Current Key Character Triggered #-------------------------------------------------------------------------- def self.character_trigger # Iterate through the list of input characters for i in 0...@input_characters.size # Set a temporary variable to the value of the current key key = @input_characters[i] # Skip if the character is not currently triggered next unless self.trigger?(key) # Get the current key's scan code scan_code = @mapped_keys[i] # Get the specified character character = get_character(key, scan_code) # Skip if there was no translation for the character next if !character || character == -1 # Return the translated character return character end # Return blank if no characters were returned return "" end #-------------------------------------------------------------------------- # * Return Current Key Character Repeated #-------------------------------------------------------------------------- def self.character_repeat # Iterate through the list of input characters for i in 0...@input_characters.size # Set a temporary variable to the value of the current key key = @input_characters[i] # Skip if the character is not currently repeated next unless self.repeat?(key) # Get the current key's scan code scan_code = @mapped_keys[i] # Get the specified character character = get_character(key, scan_code) # Skip if there was no translation for the character next if !character || character == -1 # Return the translated character return character end # Return blank if no characters were returned return "" end #-------------------------------------------------------------------------- # * Get Character from Key #-------------------------------------------------------------------------- def self.get_character(key, scan_code) # Create a character buffer buffer = '0' * 10 # Translate the current key to Unicode success = @toUnicodeEx.call(key, scan_code, @keyboard_state, buffer, 5, 0, @layout) # Return false there was no translation for the character return false if success == 0 # Iterate through the dead keys for dead_key in @dead_keys # If the dead key was pressed if @getAsyncKeyState.call(dead_key) != 0 # Map the dead key scan code dead_scan = @mapVirtualKeyEx.call(dead_key, 0, @layout) # Recreate a character buffer buffer = '0' * 10 # Translate the current key to Unicode success = @toUnicodeEx.call(dead_key, dead_scan, @keyboard_state, buffer, 5, 0, @layout) # If it returns as a dead key if success == -1 # Recreate a character buffer buffer = '0' * 10 # Translate the current key to Unicode success = @toUnicodeEx.call(key, scan_code, @keyboard_state, buffer, 5, 0, @layout) end # Return false there was no translation for the character return false if success == 0 end end # Translate the characters to Ruby encoding characters = buffer.unpack('C*').pack('U*') # Create the return character array = [] # Iterate through the character buffer for i in 0...(success * 2) # Add characters to the character array array.push(characters[i]) unless array.include?(characters[i]) end # If a dead key was pressed if success == -1 # Iterate through the character buffer for i in 0...2 # Add characters to the character array array.push(characters[i]) unless array.include?(characters[i]) end end # Delete null characters array.delete_if {|byte| byte == 0} # Create an empty string for the return character character = ' ' * array.size # Iterate through the character array for i in 0...array.size # Add the character to the string character[i] = array[i] end # Return the translated character return character end #-------------------------------------------------------------------------- # * Validate Key #-------------------------------------------------------------------------- def self.validate_key(key) # Return false if key is not a number return false if !(key.is_a?(Numeric)) # Force key into the integer class key = key.to_i # Return false if the key does not exist or is not an integer return false if ((key < 0x01) || (key > 0x100) || !(key == key.to_i)) # Return that the key is valid return true end end #============================================================================== # ** Input #------------------------------------------------------------------------------ # This module performs key input processing #============================================================================== module Input # Add class data class << self #------------------------------------------------------------------------ # * Alias Methods #------------------------------------------------------------------------ # If the update method has not been aliased unless method_defined?(:keyinputmodule_input_update) # Alias the update method alias keyinputmodule_input_update update end #------------------------------------------------------------------------- # * Frame Update #------------------------------------------------------------------------- def update # Call original method keyinputmodule_input_update # Update Keys module Keys.update end end end
class << Input Key_UP = [Keys::UP,Keys::W] Key_DOWN = [Keys::DOWN,Keys::S] Key_LEFT = [Keys::LEFT,Keys::A] Key_RIGHT = [Keys::RIGHT,Keys::D] alias :o_press :press? def press?(num) return true if num==Input::UP && Key_UP.any?{ |key| Keys.press?(key) } return true if num==Input::DOWN && Key_DOWN.any?{ |key| Keys.press?(key) } return true if num==Input::LEFT && Key_LEFT.any?{ |key| Keys.press?(key) } return true if num==Input::RIGHT && Key_RIGHT.any?{ |key| Keys.press?(key) } o_press(num) end alias :o_repeat :repeat? def repeat?(num) return true if num==Input::UP && Key_UP.any?{ |key| Keys.repeat?(key) } return true if num==Input::DOWN && Key_DOWN.any?{ |key| Keys.repeat?(key) } return true if num==Input::LEFT && Key_LEFT.any?{ |key| Keys.repeat?(key) } return true if num==Input::RIGHT && Key_RIGHT.any?{ |key| Keys.repeat?(key) } o_repeat(num) end alias :o_trigger :trigger? def trigger?(num) return true if num==Input::UP && Key_UP.any?{ |key| Keys.trigger?(key) } return true if num==Input::DOWN && Key_DOWN.any?{ |key| Keys.trigger?(key) } return true if num==Input::LEFT && Key_LEFT.any?{ |key| Keys.trigger?(key) } return true if num==Input::RIGHT && Key_RIGHT.any?{ |key| Keys.trigger?(key) } o_trigger(num) end def dir4() return 8 if press?(Input::UP) return 4 if press?(Input::LEFT) return 6 if press?(Input::RIGHT) return 2 if press?(Input::DOWN) 0 end def dir8() dir = press?(Input::UP) ? 8 : 0 dir = press?(Input::LEFT) ? dir==0 ? 4 : 7 : dir return dir if dir == 7 dir = press?(Input::RIGHT) ? dir==4 ? 0 : dir==8 ? 9 : 6 : dir return dir if dir == 9 press?(Input::DOWN) ? dir==8 ? 0 : dir==4 ? 1 : dir==6 ? 3 : 2 : dir end end
QQ截图20210130125834.png (11.8 KB, 下载次数: 62)
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |