Simple Keyboard Input
(RPG Maker XP/VX/Ace)
by KotatsuAkira / AkiraKotatsuhime
Einführung
Dieses Script habe ich letztes Jahr infolge einer Anfrage aus einem Spiel, an dem ich hin und wieder bastel, rausgeschnitten und diese Version nun spontan wiedergefunden. Es ermöglicht eine einfache Abfrage der kompletten Tastatur in jeder Version der RGSS-Engine (nicht in Ersatz-Engines), allerdings muss im Fall von RPGXP/VX .force_encoding("ASCII-8BIT") aus Zeile #17 entfernt werden.
Features
Wie beim gewöhnlichen Inputmodul der RGSS-Engine verfügt Keyboard über die Funktionen press?, trigger?, repeat?, dir4 und dir8, die den exakten Zweck ihres jeweiligen Vorbildes erfüllen sollen. Als Parameter bei den drei erstgenannten werden VirtualKey-Nummern anstelle von Input-IDs/Konstanten oder Symbolen verwendet.
Neu hinzu kommen die Funktionen toggle?, caps_lock?, num_lock? und scroll_lock?, die überprüfen, ob sich eine beliebige bzw. eine der drei wirklich dafür sinnvollen Tasten gerade im aktivierten Zustand befindet.
Praktische Anwendung
Die Nutzung geschieht vollständig auf eigene Gefahr und ist für Leute mit Script-Erfahrung gedacht, die eigenen Code schreiben wollen, in dem es zum Einsatz kommen soll. Um das Script anzuwenden, muss, nachdem es oberhalb von Main an einer passenden Position eingefügt wurde, an Codestellen, wo Eingaben in einem Frame-Update eingeholt werden sollen, Keyboard.update aufgerufen werden, der Rest geschieht wie gewohnt.
FAQ
Q: Wer kommt in die Credits dafür?
A: Na ich natürlich. Das Script darf auch jederzeit alleinstehend kostenfrei weitergegeben werden, solange alle Hinweise am oberen Rand des Codeblocks dabei intakt bleiben.
Q: Ist es kompatibel mit (Scripte hier einfügen)?
A: Keine Ahnung, eigentlich sollte es mit allen RPGXP-/-VX-/-Ace-Spielen funktionieren und kein anderes Modul in sich haben, das zufällig auch "Keyboard" heißt. Dann wäre es aber sehr wahrscheinlich, dass dieses oder ein anderes Script redundant ist.
Q: Win32API existiert nicht, was soll ich tun?
A: Wie schon oben klargestellt, funktioniert dieses Script nicht mit einer Ersatz-Engine. Diese sind nämlich für gewöhnlich nicht exklusiv auf Windows ausgerichtet, wovon diese Funktionalität jedoch direkt abhängig ist.
Q: Mein Computer ist explodiert!
A: Das ist nichtmal eine Frage. Und habe ich schon erwähnt, dass Nutzung auf eigene Gefahr geschieht?
Der Code
#==============================================================================
# ** Simple Keyboard Input
#------------------------------------------------------------------------------
# © 2022 KotatsuAkira / AkiraKotatsuhime
# Redistribute only with this copyright notice intact.
#==============================================================================
module Keyboard
#--------------------------------------------------------------------------
# * Module Constants
#--------------------------------------------------------------------------
KeyboardState = Win32API.new('user32', 'GetKeyboardState', 'P', 'L')
#--------------------------------------------------------------------------
# * Module Variables
#--------------------------------------------------------------------------
@@result = nil
@@data = ("\0" * 256).force_encoding("ASCII-8BIT")
@@states = Hash.new {|sh, sk| sh[sk] = 0 }
@@pressed_keys = [false] * 256
@@press_order = []
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def self.update
@@result = KeyboardState.call(@@data)
@@pressed_keys = (0..255).select do |sk|
(@@states[sk] = @@data[sk].ord >= 128 ? @@states[sk] + 1 : 0).nonzero?
end
@@states.each_key {|sk| @@states[sk] -= 6 if @@states[sk] >= 30 }
@@pressed_keys.each {|sk| @@press_order.push_once(sk) }
@@states.each {|sk, sv| @@press_order.delete(sk) unless sv }
end
#--------------------------------------------------------------------------
# * Check if Key is pressed down
#--------------------------------------------------------------------------
def self.press?(si)
return @@states[si] > 0
end
#--------------------------------------------------------------------------
# * Check if Keypress started right now
#--------------------------------------------------------------------------
def self.trigger?(si)
return @@states[si] == 1
end
#--------------------------------------------------------------------------
# * Check if Keypress has interval
#--------------------------------------------------------------------------
def self.repeat?(si)
st = @@states[si]
return st == 1 || st > 23 && st % 6 == 0
end
#--------------------------------------------------------------------------
# * Check if toggleable Key is active
#--------------------------------------------------------------------------
def self.toggle?(si)
return @@data[si].ord & 1 == 1
end
#--------------------------------------------------------------------------
# * Check if CapsLock is active
#--------------------------------------------------------------------------
def self.caps_lock?
return toggle?(0x14)
end
#--------------------------------------------------------------------------
# * Check if NumLock is active
#--------------------------------------------------------------------------
def self.num_lock?
return toggle?(0x90)
end
#--------------------------------------------------------------------------
# * Check if ScrollLock is active
#--------------------------------------------------------------------------
def self.scroll_lock?
return toggle?(0x91)
end
#--------------------------------------------------------------------------
# * Get even direction Keypress
#--------------------------------------------------------------------------
def self.dir4(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
return 8 if s1 > s2 && s1 > s3 && s1 > s4
return 2 if s2 > s1 && s2 > s3 && s2 > s4
return 4 if s3 > s1 && s3 > s2 && s3 > s4
return 6 if s4 > s1 && s4 > s2 && s4 > s3
return 5
end
#--------------------------------------------------------------------------
# * Get even or diagonal direction Keypress
#--------------------------------------------------------------------------
def self.dir8(su=0x26, sd=0x28, sl=0x25, sr=0x27)
s1 = @@press_order.index(su) || -1
s2 = @@press_order.index(sd) || -1
s3 = @@press_order.index(sl) || -1
s4 = @@press_order.index(sr) || -1
if s1 > s2
return s3 > s4 ? 7 : s4 > s3 ? 9 : 8
elsif s2 > s1
return s3 > s4 ? 1 : s4 > s3 ? 3 : 2
else
return s3 > s4 ? 4 : s4 > s3 ? 6 : 5
end
return 5
end
#--------------------------------------------------------------------------
# * Inspect Object
#--------------------------------------------------------------------------
def self.inspect
return "#<Keyboard {#{@@pressed_keys.join(',')}}>"
end
end
Alles anzeigen
~炬燵あ