Keymanager, Keywrapper (Timer)

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DivineDominion

Betreff: Keymanager, Keywrapper (Timer)

BeitragMo, Mai 16, 2005 19:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Man muss in der Mainloop KEYMANAGER.changeStatus( ) anwenden, damit alle Stadien aktualisiert werden. Saugt nicht am Speed und hat mir viele treue Dienste erwiesen.

Es werden 255 Scancodes kontrolliert und mit einem Status versehen, womit man sachen wie KeyHit, KeyDown, KeyUp zur verfügung hat. isHit() lässt sich beliebig oft aufrufen, im Gegensatz zu dem leidigen Problem mit KeyHit Smile

Der Keywrapper hingegen ist für das Timing zuständig. Wrappt man Tasten mit ihm, registriert er die Zeit und gibt ein "hit" an. Hält man gedrückt wartet er eine Weile, bis er in einen neuen Zustand verfällt. Hämmert man oft hintereinander auf die Taste, liefert er jedes mal ein "hit". Das ist dann schneller als der zweite Zustand, der folgendes tut: Es wird ein "hit" geliefert und eine kurze weile gewartet, dann wieder; so lange, bis man loslässt. Damit kann man langsam mit dem Cursor durch Menüs in Spielen oder mit einem Textcursor in Textdateien rumfliegen Smile

Für ein Beispiel schaut euch den Beispielcode der Konsolenähnlichen Texteingabe an.

Vielleicht hilft's ja wem.

Code: [AUSKLAPPEN]
Rem
Module AFX.Keymanager

ModuleInfo "Version: 1.0"
ModuleInfo "Author: Christian ~qDivineDominion~q Tietze"
ModuleInfo "License: Public Domain"
ModuleInfo "Copyright: http://divinedominion.art-fx.org"
ModuleInfo "Modserver: BRL"
EndRem

Rem
Strict

Import brl.basic
Import brl.system
Import brl.keycodes
EndRem

Global KEYMANAGER:TKeyManager = New TKeyManager
Global KEYWRAPPER:TKeyWrapper = New TKeyWrapper

'Tastenstadien
Const KEY_STATE_NORMAL = 0
Const KEY_STATE_HIT = 1
Const KEY_STATE_DOWN = 2
Const KEY_STATE_UP = 3

Type TKeyManager
   
   'Array aller Tasten die man zur Auswahl hat
   Field _iKeyStatus:Int[256]
         
   Rem
      Statusabfragen
   EndRem
   
   Method isNormal:Int( iKey:Int )
      
      If Self._iKeyStatus[ iKey ] = KEY_STATE_NORMAL Then Return True Else Return False
         
   EndMethod
   
   Method isHit:Int( iKey:Int )
      
      If Self._iKeyStatus[ iKey ] = KEY_STATE_HIT Then Return True Else Return False

   EndMethod
   
   Method isDown:Int( iKey:Int )
   
      If Self._iKeyStatus[ iKey ] = KEY_STATE_DOWN Then Return True Else Return False

   EndMethod
   
   Method isUp:Int( iKey:Int )      
      
      If Self._iKeyStatus[ iKey ] = KEY_STATE_UP Then Return True Else Return False

   EndMethod
   
   
   Rem
      changeStatus(  )
      
      Iteriert alle Tasten (gespeichert in lokalem Array)
      und ändert ggf. deren Status.
   EndRem
   Method changeStatus(  )
   
      For Local i:Int = 1 To 255
         
         If _iKeyStatus[ i ] = KEY_STATE_NORMAL
            
            If KeyDown( i ) Then _iKeyStatus[ i ] = KEY_STATE_HIT
            
         ElseIf _iKeyStatus[ i ] = KEY_STATE_HIT
            
            If KeyDown( i ) Then _iKeyStatus[ i ] = KEY_STATE_DOWN Else _iKeyStatus[ i ] = KEY_STATE_UP
            
         ElseIf _iKeyStatus[ i ] = KEY_STATE_DOWN
         
            If Not KeyDown( i ) Then _iKeyStatus[ i ] = KEY_STATE_UP
            
         ElseIf _iKeyStatus[ i ] = KEY_STATE_UP
            
            _iKeyStatus[ i ] = KEY_STATE_NORMAL
            
         EndIf
         
      Next
      
   EndMethod
   
   Method getStatus:Int( iKey:Int )
      
      Return _iKeyStatus[ iKey ]
      
   EndMethod
   
EndType

Const KEYWRAP_ALLOW_HIT = %01
Const KEYWRAP_ALLOW_HOLD = %10
Const KEYWRAP_ALLOW_BOTH = %11

Type TKeyWrapper
   
   Rem
      0 - Allow-Rule
      1 - Pausenlänge für Hold nach Hit
      2 - Pausenlänge für Hold nach Hold
      3 - Gesamtzeit bis zum nächsten Hold
   EndRem
   Field _iKeySet:Int[256, 4]
   
   Method allowKey( iKey:Int, iRule:Int = KEYWRAP_ALLOW_BOTH, iHitTime:Int = 500, iHoldtime:Int = 70 )
      
      _iKeySet[iKey, 0] = iRule
      
      If iRule & KEYWRAP_ALLOW_HIT
         
         _iKeySet[iKey, 1] = iHitTime
      
      EndIf
      
      If iRule & KEYWRAP_ALLOW_HOLD
         
         _iKeySet[iKey, 2] = iHoldTime
         
      EndIf
      
   EndMethod
   
   Method pressedKey:Int( iKey:Int )
      
      Local iKeyState:Int = KEYMANAGER.getStatus( iKey )
      Local iRule:Int = _iKeySet[iKey, 0]
      
      If iKeyState = KEY_STATE_NORMAL Or iKeyState = KEY_STATE_UP Then Return False
      
      'Muss erlaubt und aktiv sein
      If iRule & KEYWRAP_ALLOW_HIT And iKeyState = KEY_STATE_HIT
         
         Return hitKey( iKey )
         
      ElseIf iRule & KEYWRAP_ALLOW_HOLD
         
         Return holdKey( iKey )
         
      EndIf
      
      Return False
      
   EndMethod
   
   Method hitKey:Int( iKey:Int )
      
      Local iRule:Int = _iKeySet[iKey, 0]
      
      'If iKeyState <> KEY_STATE_HIT Then Return False
      
      'Muss erlaubt und aktiv sein
      If iRule & KEYWRAP_ALLOW_HIT' And iKeyState = KEY_STATE_HIT
         
         'Zeit bis man Taste halten darf
         _iKeySet[iKey, 3] = MilliSecs(  ) + _iKeySet[iKey, 1]
         
         Return True
         
      EndIf
      
      Return False
      
   EndMethod
   
   Method holdKey:Int( iKey:Int )
      
      Local iRule:Int = _iKeySet[iKey, 0]
      
      'If iKeyState = KEY_STATE_NORMAL Or iKeyState = KEY_STATE_UP Then Return False
      
      If iRule & KEYWRAP_ALLOW_HOLD
         
         'Zeit die verstrichen sein muss
         Local iTime:Int = _iKeySet[iKey, 3]
         
         If MilliSecs(  ) > iTime
            
            'Zeit bis zum nächsten Halten aktualisieren
            _iKeySet[iKey, 3] = MilliSecs(  ) + _iKeySet[iKey, 2]
            
            Return True
         
         EndIf
         
      EndIf
      
      Return False
         
   EndMethod
   
   Method resetKey( iKey:Int )
      
      _iKeySet[iKey, 0] = 0
      _iKeySet[iKey, 1] = 0
      _iKeySet[iKey, 2] = 0
      _iKeySet[iKey, 3] = 0
      
   EndMethod
EndType
christian.tietze@gmail.com - https://christiantietze.de
macOS

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group