Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Smooth Button Input Processing

I know that this is now done with the conditional branch, but I have an image being displayed when the button is pressed. The problem is that it can be picky, once the image comes up it'll disappear again because the button was pressed too long. I was curious if there was a way to make it smoother, ie. if i pressed it for an hour it would register as being pressed once, and the same for short periods. I remember seeing it the way I would like it at one point but I don't remember how. I apologize if this is an extremely stupid question and appreciate any help.
 
I recently found a keyboard script, which shows some of the methods of Input class. I think your problem has something to do with the variables '@counts' and @delay which handle the delay. @counts is set to 4 and reduced once per frame, when 0 the key is being held down. When it reaches 4 it is set back to 0 (by @counts %=@delay).
Code:
 

################################################################################

#  Input - General_Yorr - v2.0                                                 #

#                                                                              #

#  Contains module Input and module Keys                                       #

#  Created by General_Yorr                                                     #

#  Completed on July 14, 2006                                                  #

################################################################################

# Disclaimer:                                                                  #

#   The Keys module was extracted from the Kboard module written by cybersam.  #

#   My ONLY additions were the attr_reader and each function.                  #

#                                                                              #

#   The comments on some of the methods were modified from the help file in    #

#   RPG Maker XP.                                                              #

################################################################################

# Version History:                                                             #

#   1.0 - Basic keyboard input working. Accepts individual key or key types to #

#         test to see if they are pressed. Mulitply key input supported.       #

#                                                                              #

#   1.1 - Minor update. Removed unneccesary code and added some additional     #

#         comments.                                                            #

#         Replaced delay literal with class variable.                          #

#         Added version history.                                               #

#                                                                              #

#   1.2 - Added Keys module, edited code to fit new module.                    #

#                                                                              #

#   2.0 - Added toggle? function.                                              #

#         Added toggled? function.                                             #

#         Added triggered? function.                                           #

#         Added repeated? function.                                            #

#         Added repeating? function.                                           #

#         Added pressed? function.                                             #

#         Added removeGroup function.                                          #

#         Added remGroup function.                                             #

#         Added removeGroups function.                                         #

#         Added remGroups function.                                            #

#         Added additional instructions on use of the module/script.           #

################################################################################

# This module was created to be used in RPG Maker XP. It overrides the default #

# Input in such a way that all of the keyboard is accessable.                  #

################################################################################

# Instructions:                                                                #

#   Put this script before all the other scripts in your project. You use the  #

#   Input module the same way that you would use the default Input module.     #

#   If you want to know if the key 'k' was just pressed you would put          #

#                       Input::trigger?(Keys::KEY_K)                           #

#   This will return true if the 'k' key was just pressed.                     #

#                                                                              #

#   To make the default code still funtion, the Input module has certain keys  #

#   grouped together. These groups are accessed through the Input module, so   #

#   if you wanted to know if one of the keys in the group 'A' was down, you    #

#   would put                                                                  #

#                       Input::repeat?(Input::A)                               #

#   It will return true if any of the keys in the group 'A' are being pressed. #

#                                                                              #

#   The following default functions are defined:                               #

#     trigger?                                                                 #

#     repeat?                                                                  #

#     press?                                                                   #

#     dir4                                                                     #

#     dir8                                                                     #

#     update                                                                   #

#   These all work as the originals did with the exception of the functions    #

#   that take keys can take either a key type or an individual key as opposed  #

#   to just key types.                                                         #

#                                                                              #

#   The following funcitons are aliased copies of the above:                   #

#     triggered?                                                               #

#     repeated?                                                                #

#     repeating?                                                               #

#     pressed?                                                                 #

#   They are aliased to the expected functions.                                #

#                                                                              #

#   The following functions are additions:                                     #

#     toggle? / toggled?                                                       #

#     getKeys                                                                  #

#     addKey                                                                   #

#     addKeys                                                                  #

#     removeKey / remKey                                                       #

#     removeKeys / remKeys                                                     #

#     removeGroup / remGroup                                                   #

#                                                                              #

#   The toggle? function returns true if the key it toggled on and false if it #

#   is toggled off. If you request a toggle on a group of keys that has more   #

#   than one element in it, it returns false, and if you request a toggle on a #

#   group with a single element in it, it returns the toggle of that key.      #

#   Every key has a toggle, but toggle? makes the most sense when refering to  #

#   keys like Caps Lock.                                                       #

#                                                                              #

#   The getKeys function takes a group of keys as an argument and returns a    #

#   copy of the array containing all the keys in that group.                   #

#                                                                              #

#   The addKey function takes a group and a key as arguments. It then removes  #

#   the key from any other group and adds it to the group. Returns false if    #

#   it fails, true otherwise. Could fail on removing the key. See removeKey    #

#                                                                              #

#   The addKeys function takes a group and an array of keys as arguments. It   #

#   returns a hash that maps each key to either true or false depending on if  #

#   that particular key succeeds in addKey.                                    #

#                                                                              #

#   addKey and addKeys can be used to create new groups in the Input module.   #

#   These groups, however, will not have constants defined in Input for them,  #

#   you will have to take care of keeping that yourself.                       #

#                                                                              #

#   The removeKey / remKey functions take a group and a key as arguments. It   #

#   returns false if the key is the only element of the group. Otherwise it    #

#   returns true.                                                              #

#                                                                              #

#   The removeKeys / remKeys functions take a group and an array of keys as    #

#   arguments. Returns true if it successfully removes ALL of the keys. If it  #

#   cannot remove them all, it will remove NONE of them and return false.      #

#                                                                              #

#   The removeGroup / remGroup functions take a group as an argument and       #

#   removes all of the elements from it. Returns false if the argument is not  #

#   a group of keys, true otherwise.                                           #

#                                                                              #

#   The removeGroups / remGroups functions take an array of groups as an       #

#   argument and returns a hash mapping each group to wether it was a group    #

#   or not.                                                                    #

#                                                                              #

#   Default groups:                                                            #

#          UP = [Keys::KEY_UP]                                                 #

#          DOWN  = [Keys::KEY_DOWN]                                            #

#          LEFT  = [Keys::KEY_LEFT]                                            #

#          RIGHT = [Keys::KEY_RIGHT]                                           #

#          A     = [Keys::KEY_LSHIFT, Keys::KEY_RSHIFT,  Keys::KEY_Z]          #

#          B     = [Keys::KEY_ESCAPE, Keys::KEY_NUMPAD0, Keys::KEY_X]          #

#          C     = [Keys::KEY_SPACE,  Keys::KEY_RETURN,  Keys::KEY_C]          #

#          X     = [Keys::KEY_A]                                               #

#          Y     = [Keys::KEY_S]                                               #

#          Z     = [Keys::KEY_D]                                               #

#          L     = [Keys::KEY_Q]                                               #

#          R     = [Keys::KEY_W]                                               #

#          SHIFT = [Keys::KEY_SHIFT,    Keys::KEY_LSHIFT,  Keys::KEY_RSHIFT]   #

#          CTRL  = [Keys::KEY_LCONTROL, Keys::KEY_RCONTROL]                    #

#          ALT   = [Keys::KEY_L_ALT,    Keys::KEY_R_ALT]                       #

################################################################################

 

 

module Keys

 KEY_BACK      = 0x08        # BACKSPACE Keys

 KEY_TAB       = 0x09        # TAB Keys

 KEY_RETURN    = 0x0D        # ENTER Keys

 KEY_SHIFT     = 0x10        # SHIFT Keys

 KEY_PAUSE     = 0x13        # PAUSE Keys

 KEY_CAPITAL   = 0x14        # CAPS LOCK Keys

 KEY_CAPSLOCK  = 0x14        # CAPS LOCK Key

 KEY_ESCAPE    = 0x1B        # ESC Keys

 KEY_SPACE     = 0x20        # SPACEBAR

 KEY_PRIOR     = 0x21        # PAGE UP Keys

 KEY_NEXT      = 0x22        # PAGE DOWN Keys

 KEY_END       = 0x23        # END Keys

 KEY_HOME      = 0x24        # HOME Keys

 KEY_LEFT      = 0x25        # LEFT ARROW Keys

 KEY_UP        = 0x26        # UP ARROW Keys

 KEY_RIGHT     = 0x27        # RIGHT ARROW Keys

 KEY_DOWN      = 0x28        # DOWN ARROW Keys

 KEY_SELECT    = 0x29        # SELECT Keys

 KEY_PRINT     = 0x2A        # PRINT Keys

 KEY_SNAPSHOT  = 0x2C        # PRINT SCREEN Keys

 KEY_INSERT    = 0x2D        # INS Keys

 KEY_DELETE    = 0x2E        # DEL Keys

 

 KEY_0         = 0x30        # 0 Keys

 KEY_1         = 0x31        # 1 Keys

 KEY_2         = 0x32        # 2 Keys

 KEY_3         = 0x33        # 3 Keys

 KEY_4         = 0x34        # 4 Keys

 KEY_5         = 0x35        # 5 Keys

 KEY_6         = 0x36        # 6 Keys

 KEY_7         = 0x37        # 7 Keys

 KEY_8         = 0x38        # 8 Keys

 KEY_9         = 0x39        # 9 Keys

 

 KEY_A         = 0x41        # A Keys

 KEY_B         = 0x42        # B Keys

 KEY_C         = 0x43        # C Keys

 KEY_D         = 0x44        # D Keys

 KEY_E         = 0x45        # E Keys

 KEY_F         = 0x46        # F Keys

 KEY_G         = 0x47        # G Keys

 KEY_H         = 0x48        # H Keys

 KEY_I         = 0x49        # I Keys

 KEY_J         = 0x4A        # J Keys

 KEY_K         = 0x4B        # K Keys

 KEY_L         = 0x4C        # L Keys

 KEY_M         = 0x4D        # M Keys

 KEY_N         = 0x4E        # N Keys

 KEY_O         = 0x4F        # O Keys

 KEY_P         = 0x50        # P Keys

 KEY_Q         = 0x51        # Q Keys

 KEY_R         = 0x52        # R Keys

 KEY_S         = 0x53        # S Keys

 KEY_T         = 0x54        # T Keys

 KEY_U         = 0x55        # U Keys

 KEY_V         = 0x56        # V Keys

 KEY_W         = 0x57        # W Keys

 KEY_X         = 0x58        # X Keys

 KEY_Y         = 0x59        # Y Keys

 KEY_Z         = 0x5A        # Z Keys

 

 KEY_LWIN      = 0x5B        # Left Windows Keys (Microsoft Natural Keysboard)

 KEY_RWIN      = 0x5C        # Right Windows Keys (Natural Keysboard)

 KEY_APPS      = 0x5D        # Applications Keys (Natural Keysboard)

 

 KEY_NUMPAD0   = 0x60        # Numeric Keyspad 0 Keys

 KEY_NUMPAD1   = 0x61        # Numeric Keyspad 1 Keys

 KEY_NUMPAD2   = 0x62        # Numeric Keyspad 2 Keys

 KEY_NUMPAD3   = 0x63        # Numeric Keyspad 3 Keys

 KEY_NUMPAD4   = 0x64        # Numeric Keyspad 4 Keys

 KEY_NUMPAD5   = 0x65        # Numeric Keyspad 5 Keys

 KEY_NUMPAD6   = 0x66        # Numeric Keyspad 6 Keys

 KEY_NUMPAD7   = 0x67        # Numeric Keyspad 7 Keys

 KEY_NUMPAD8   = 0x68        # Numeric Keyspad 8 Keys

 KEY_NUMPAD9   = 0x69        # Numeric Keyspad 9 Keys

 KEY_MULTIPLY  = 0x6A        # Multiply Keys (*)

 KEY_ADD       = 0x6B        # Add Keys (+)

 KEY_SEPARATOR = 0x6C        # Separator Keys

 KEY_SUBTRACT  = 0x6D        # Subtract Keys (-)

 KEY_DECIMAL   = 0x6E        # Decimal Keys

 KEY_DIVIDE    = 0x6F        # Divide Keys (/)

 

 KEY_F1        = 0x70        # F1 Keys

 KEY_F2        = 0x71        # F2 Keys

 KEY_F3        = 0x72        # F3 Keys

 KEY_F4        = 0x73        # F4 Keys

 KEY_F5        = 0x74        # F5 Keys

 KEY_F6        = 0x75        # F6 Keys

 KEY_F7        = 0x76        # F7 Keys

 KEY_F8        = 0x77        # F8 Keys

 KEY_F9        = 0x78        # F9 Keys

 KEY_F10       = 0x79        # F10 Keys

 KEY_F11       = 0x7A        # F11 Keys

 KEY_F12       = 0x7B        # F12 Keys

 

 KEY_NUMLOCK   = 0x90        # NUM LOCK Keys

 KEY_SCROLL    = 0x91        # SCROLL LOCK Keys

 

 KEY_LSHIFT   = 0xA0        # Left SHIFT Keys

 KEY_RSHIFT   = 0xA1        # Right SHIFT Keys

 KEY_LCONTROL  = 0xA2        # Left CONTROL Keys

 KEY_RCONTROL  = 0xA3        # Right CONTROL Keys

 KEY_L_ALT     = 0xA4        # Left ALT Keys

 KEY_R_ALT     = 0xA5        # Right ALT Keys

 

 KEY_SEP       = 0xBC        # , Keys

 KEY_DASH     = 0xBD        # - Keys

 KEY_DOTT     = 0xBE        # . Keys

   

 for i in self.constants

   attr_reader i

 end

 

 module_function

 

 def each

   for i in self.constants

     yield self.const_get(i)

   end

 end

end

 

 

module Input

 

# Constants that need to be defined for overriding purposes

 F5      = Keys::KEY_F5

 F6      = Keys::KEY_F6

 F7      = Keys::KEY_F7

 F8      = Keys::KEY_F8

 F9      = Keys::KEY_F9

 

 

 UP      = 1000

 DOWN    = 1001

 LEFT    = 1002

 RIGHT   = 1003

 

 A       = 2000

 B       = 2001

 C       = 2002

 

 X       = 3000

 Y       = 3001

 Z       = 3002

 

 R       = 4000

 L       = 4001

 

 SHIFT   = 5000

 CTRL    = 5001

 ALT     = 5002

 

 for i in self.constants

   attr_reader i

 end

 

 @KeysMap  = Hash.new

 @trigger = Hash.new(false)

 @repeat  = Hash.new(false)

 @toggle  = Hash.new(false)

 @counts  = Hash.new(0)

 

 @delay = 5 # The number of frames in which repeat? will only return true once

 

# an array containing all the Keyss that correspond to the direction up, down,

# left, right, 'A', 'B', 'C', 'X', 'Y', 'Z', 'L', 'R', SHIFT, CTRL, and ALT,

# respectively.

 @KeysMap[UP]    = [Keys::KEY_UP]    

 @KeysMap[DOWN]  = [Keys::KEY_DOWN]

 @KeysMap[LEFT]  = [Keys::KEY_LEFT]

 @KeysMap[RIGHT] = [Keys::KEY_RIGHT]

 

 @KeysMap[A] = [Keys::KEY_LSHIFT, Keys::KEY_RSHIFT,  Keys::KEY_Z]

 @KeysMap[B] = [Keys::KEY_ESCAPE, Keys::KEY_NUMPAD0, Keys::KEY_X]

 @KeysMap[C] = [Keys::KEY_SPACE,  Keys::KEY_RETURN,  Keys::KEY_C]

 

 @KeysMap[X] = [Keys::KEY_A]

 @KeysMap[Y] = [Keys::KEY_S]

 @KeysMap[Z] = [Keys::KEY_D]

 

 @KeysMap[L] = [Keys::KEY_Q]

 @KeysMap[R] = [Keys::KEY_W]

 

 @KeysMap[SHIFT] = [Keys::KEY_SHIFT,    Keys::KEY_LSHIFT,  Keys::KEY_RSHIFT]

 @KeysMap[CTRL]  = [Keys::KEY_LCONTROL, Keys::KEY_RCONTROL]

 @KeysMap[ALT]   = [Keys::KEY_L_ALT,    Keys::KEY_R_ALT]

 

 @KeyStates = 0.chr * 256

 

 @getKeyStates = Win32API.new('user32', 'GetKeyboardState', ['P'], 'N')

 

 for i in Keys

   @trigger[i] = false

   @repeat[i]  = false

   @counts[i]  = 4

 end

 

 module_function

 

# Determines whether the button num was pressed agian at the last update.

# "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.

 def trigger?(num)

   if @KeysMap.has_key?(num)

     for i in @KeysMap[num]

       return true if @trigger[i]

     end

     return false

   end

   

   return @trigger[num]

 end

 

 alias triggered? trigger?

 

# Determines whether the button num was being pressed at the last update.

# Unlike trigger?, 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.

# Has a delay to prevent things from moving to fast, E.G. menu indecies.

 def repeat?(num)

   

   if @KeysMap.has_key?(num)

     for i in @KeysMap[num]

       return true if(@repeat[i] and @counts[i] == 0)

     end

     return false

   end

   

   return (@repeat[num] and @counts[i] == 0)

 end

 

 alias repeated? repeat?

 alias repeating? repeat?

 

# Same as repeat without the delay

 def press?(num)

   if @KeysMap.has_key?(num)

     for i in @KeysMap[num]

       return true if @repeat[i]

     end

     return false

   end

   

   return @repeat[i]

 end

 

 alias pressed? press?

 

 def toggle?(num)

   if @KeysMap.has_key?(num)

     return false if @KeysMap[num].size != 1

     return @toggle[@KeysMap[num][0]]

   end

   

   return @toggle[num]

 end

 

 alias toggled? toggle?

 

# Checks the status of the directional buttons, translates the data into a

# specialized 4-direction input format, and returns the number pad equivalent

# (2, 4, 6, 8).

# If no directional buttons are being pressed (or the equivalent), returns 0.

 def dir4

   dir = 0

   for i in @KeysMap[UP]

     if @repeat[i]

       dir = 8

     end

   end

   

   for i in @KeysMap[DOWN]

     if @repeat[i]

       if dir == 0

         dir = 2

       else

         return 0

       end

     end

   end

   

   for i in @KeysMap[LEFT]

     if @repeat[i]

       if dir == 0

         dir = 4

       else

         return 0

       end

     end

   end

   

   for i in @KeysMap[RIGHT]

     if @repeat[i]

       if dir == 0

         dir = 6

       else

         return 0

       end

     end

   end

   

   return dir

 end

 

# Checks the status of the directional buttons, translates the data into a

# specialized 8-direction input format, and returns the number pad equivalent

# (1, 2, 3, 4, 6, 7, 8, 9).

# If no directional buttons are being pressed (or the equivalent), returns 0.

 def dir8

   dir = dir4

   

   if dir > 0

     return dir

   end

   

   for i in @KeysMap[UP]

     if @repeat[i]

       dir = 8

     end

   end

   

   for i in @KeysMap[LEFT]

     if @repeat[i]

       case dir

         when 0, 4

           dir = 4

         when 7, 8

           dir = 7

       end

     end

   end

   

   for i in @KeysMap[RIGHT]

     if @repeat[i]

       case dir == 0

         when 0, 6

           dir = 6

         when 4, 9

           dir = 9

         else

           return 0

       end

     end

   end

   

   for i in @KeysMap[DOWN]

     if @repeat[i]

       case dir

         when 0, 2

           dir = 2

         when 3, 6

           dir = 3

         when 1, 4

           dir = 1

       else

         return 0

       end

     end

   end

   

   return dir

 end

 

# Updates input data. As a rule, this method is called once per frame.

 def update

   @getKeyStates.call(@KeyStates)

 

   for i in Keys

     @toggle[i] = (@KeyStates[i] & 0x01 == 0x01)

     if (@KeyStates[i] & 0x80 > 0)

       @trigger[i] = !@repeat[i]

       @repeat[i] = true

       

       @counts[i] += 1

       @counts[i] %= @delay

     else

       @repeat[i]  = false

       @trigger[i] = false

       

       @counts[i] = -1

     end

   end

 end

 

 

 # Additional functions of use

 def getKeys(keyType)

   if @KeysMap.has_key?(keyType)

     return @KeysMap[keyType].dup

   end

   return [keyType]

 end

 

 def addKey(keyType, key)

   legit = true

   @KeysMap.each_key {| i | legit = remKey(i, key)}

   

   return false if !legit

 

   if @KeysMap.has_key?(keyType)

     @KeysMap[keyType] = @KeysMap[keyType] | [key]

   else

     @KeysMap[KeyType] = [key]

   end

   return true

 end

 

 def addKeys(keyType, keys)

   legits = Hash.new(false)

   

   for i in keys

     legits[i] = addKey(keyType, i)

   end

   

   return legits

 end

 

 def removeKey(keyType, key)

   return true if !@KeysMap.has_key?(keyType)

   return false if @KeysMap[keyType] == [key]

   @KeysMap[keyType] -= key

   return true

 end

 

 def removeKeys(keyType, keys)

   return true if !@KeysMap.has_key?(keyType)

   return false if @KeysMap[keyType].size <= keys.size

   

   for i in keys

     return false if !@KeysMap[keyType].include?(i)

   end

   

   for i in keys

     @KeysMap[keyType].remove(i)

   end

   return true

 end

 

 alias remKey removeKey

 alias remKeys removeKeys

 

 def removeGroup(keyGroup)

   return false if !@KeysMap.has_key?(keyGroup)

   @KeysMap[keyGroup] = []

   

   return true;

 end

 

 alias remGroup removeGroup

 

 def removeGroups(keyGroups)

   ligits = Hash.new(false)

   

   for i in keyGroups

     ligits[i] = removeGroup(i)

   end

   

   return legits

 end

 

end
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top