Konsolenähnliche Texteingabe

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DivineDominion

Betreff: Konsolenähnliche Texteingabe

BeitragMo, Mai 16, 2005 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Das hier ist ein Code, der dafür sorgt, dass eine "Tastatur" mit allen Zeichen eines Charsets am Bildschirm angezeigt wird und man mit den PFeiltasten, X, Y und C navigieren, auswählen, löschen bzw die Eingabe bestätigen kann.

Man muss vor der Mainloop einmal den Manager initialisieren, beispielsweise so:
Code: [AUSKLAPPEN]

Global hFont:TFontImage = TFontImage.load( "font.png", 8, 8, "font.txt" ) 'Link siehe unten
TEXTINPUTMANAGER.init( hFont, "charborder.png", , , "inputcursor.png" )


Starten tut man eine Eingabe mit 8 Zeichen folgendermaßen:
Code: [AUSKLAPPEN]
TEXTINPUTMANAGER.startInput( "Wie ist dein Name?", 8 )


Man muss alle anderen Sachen logischerweise blockieren während man was eingibt. Dafür muss man dann diese Funktion aufrufen (habe sie als Methode im Gamestate):
Code: [AUSKLAPPEN]


'Konfigurierbare Tasten (Gameboy-Steuerung), wird gleich benutzt, darum :)
Global BUTTON_A = KEY_X
Global BUTTON_B = KEY_Y
Global BUTTON_START = KEY_C
Global BUTTON_SELECT = KEY_D

Function handleTextInput:String(  )
   
   If TEXTINPUTMANAGER.active(  )

      'Tasten zwischenspeichern für Wrapper
      Local iKeyUp:Int, iKeyRight:Int, iKeyDown:Int, iKeyLeft:Int
      Local iKeyStateA:Int, iKeyB:Int, iKeyStart:Int
      
      'Navigieren
      iKeyUp = KEYWRAPPER.pressedKey( KEY_UP )
      iKeyRight = KEYWRAPPER.pressedKey( KEY_RIGHT )
      iKeyDown = KEYWRAPPER.pressedKey( KEY_DOWN )
      iKeyLeft = KEYWRAPPER.pressedKey( KEY_LEFT )
      
      'Aktionstasten
      iKeyStateA = KEYMANAGER.getStatus( BUTTON_A )
      iKeyB = KEYMANAGER.isHit( BUTTON_B )
      iKeyStart = KEYMANAGER.isHit( BUTTON_START )
      
      Local sText:String = TEXTINPUTMANAGER.handleKeys( iKeyUp, iKeyRight, iKeyDown, iKeyLeft, iKeyStateA, iKeyB, iKeyStart )
      
      Return sText
         
   EndIf
   
End Function


Der Keywrapper timed dabei das Verhalten der Tasten. HITted man die Tasten reagiert er sofort. Hält man gedrückt sendet er sofort ein Hit und nach einer Pause ein weiteres. Ab dann ist die Pause relativ gering, so dass man langsam durch die "Items" scrollt. Probiert es mit dem Beispiel selber aus Smile

Funktioniert nur hiermit:
- TFontImage https://www.blitzforum.de/viewtopic.php?p=115071
- TKeymanager https://www.blitzforum.de/viewtopic.php?t=11360

Beispiel: http://divinedominion.art-fx.o...ispiel.zip

bmx: http://divinedominion.art-fx.o...tInput.bmx
Hintergrund (Knöpfe) für 8x8 Font: http://divinedominion.art-fx.o...border.png
Eingabemarke: http://divinedominion.art-fx.o...cursor.bmx

Code: [AUSKLAPPEN]

Strict

Import brl.basic
Import brl.glmax2d
Import brl.pngloader
Import brl.bmploader

Import "TFontImage.bmx"
Import "TKeymanager.bmx"

Type TTextInputManager
   
   Field _iActive:Int
   
   'Titel(-frage) über Eingabe
   Field _sTitle:String
   
   'Text der eingetippt wurde
   Field _sText:String, _iMaxLength:Int
   
   'Eingabetastatur
   Field _hInput:TTextInput
   
   'Ressourcen
   Field _hFont:TFontImage
   Field _hCursorImage:TImage, _iCursorTimer:Int, _iCursorFrame:Int
   Field _hCellImage:TImage   
   
   Method init( hFont:TFontImage, sCellFile:String, iCellWidth:Int = 13, iCellHeight:Int = 13, sCursorFile:String, iCursorWidth:Int = 11, iCursorHeight:Int = 2 )
      
      _hFont = hFont   
      _hCellImage = LoadAnimImage( sCellFile, iCellWidth, iCellHeight, 0, 3 )
      _hCursorImage = LoadAnimImage( sCursorFile, iCursorWidth, iCursorHeight, 0, 2 )
      
   EndMethod
   
   Method startInput( sTitle:String, iMaxLength:Int )
      
      _sText = ""
      _sTitle = sTitle
      _iMaxLength = iMaxLength - 1
      _iActive = True
      _hInput = TTextInput.create( _hFont, _hCellImage )
            
      'Tastendruck timen
      KEYWRAPPER.allowKey( KEY_DOWN, KEYWRAP_ALLOW_BOTH )
      KEYWRAPPER.allowKey( KEY_UP, KEYWRAP_ALLOW_BOTH )
      KEYWRAPPER.allowKey( KEY_LEFT, KEYWRAP_ALLOW_BOTH )
      KEYWRAPPER.allowKey( KEY_RIGHT, KEYWRAP_ALLOW_BOTH )
      
   EndMethod
   
   Method endInput(  )
      
      _iActive = False
      
      'Tastentimer löschen
      KEYWRAPPER.resetKey( KEY_DOWN )
      KEYWRAPPER.resetKey( KEY_UP )
      KEYWRAPPER.resetKey( KEY_LEFT )
      KEYWRAPPER.resetKey( KEY_RIGHT )      
      
   EndMethod
   
   Method active:Int(  )
      
      Return _iActive
      
   EndMethod
   
   Method draw(  )
      
      If _iActive
         
         _hFont.draw( _sTitle, 0, 0 )
         
         _hInput.draw(  )
         Self.DrawText(  )
         
      EndIf
      
   EndMethod
   
   Method DrawText(  )
      
      Local i:Int = 0
      
      Local iWidthPixel:Int = ( _iMaxLength + 1 )* _hCursorImage.width
      Local x:Int = ( 160 - iWidthPixel ) / 2
      
      'Zeichenstellen einzeichnen
      For i = 0 To _iMaxLength
         
         DrawImage _hCursorImage, x + i * _hCursorImage.width, 50, 0
         
      Next
      
      'Blinkenden Cursor malen
      If _sText.length <= _iMaxLength
         
         If MilliSecs(  ) > _iCursorTimer
            
            _iCursorFrame = Not _iCursorFrame
            _iCursorTimer = MilliSecs(  ) + 400
         
         EndIf
         DrawImage _hCursorImage, x + _sText.length * _hCursorImage.width, 50, _iCursorFrame
         
      EndIf
      
      For i = 0 Until _sText.length
         
         _hFont.draw( Chr( _sText[i] ), x + i * _hCursorImage.width, 40 )
         
      Next
      
   EndMethod
   
   Method handleKeys:String( iKeyUp:Int, iKeyRight:Int, iKeyDown:Int, iKeyLeft:Int, iKeyStateA:Int, iKeyB:Int, iKeyStart:Int )
      
      If iKeyStateA = KEY_STATE_HIT
         'Ausgewähltes Zeichen hinzufügen
         
         Local sChar:String = _hInput.getSelectedChar(  )
         
         If _sText.length <= _iMaxLength
            
            _sText :+ sChar
            
         EndIf
         
         _hInput.holdKey(  )
      
      ElseIf iKeyStateA = KEY_STATE_DOWN
         'foo bar   
         
      ElseIf iKeyStateA = KEY_STATE_UP
         
         _hInput.releaseKey(  )
      
      ElseIf iKeyB
         'Zeichen löschen
         
         If _sText.length > 0
            
            _sText = _sText[.._sText.length - 1]'Left( _sText, _sText.length - 1 )
            
         EndIf
         
      ElseIf iKeyStart
         'Ggf. Eingabe beenden
         
         If _sText.length > 0
            
            Self.endInput(  )
            
            _hInput = Null
            
            Return _sText
            
         EndIf
         
      Else
         
         _hInput.moveCursor( iKeyUp, iKeyRight, iKeyDown, iKeyLeft )
         
      EndIf
      
   EndMethod
   
EndType

Type TTextInput
   
   Field _iPos:Int
   
   Field _hFont:TFontImage, _sChars:String
   Field _hCellImage:TImage
   Field _iCellW:Int, _iCellH:Int
   
   Field _iNumRows:Int, _iNumCols:Int
   
   Field _iCursorFrame:Int
   
   Field _w:Int, _h:Int
   
   Function create:TTextInput( hFont:TFontImage, hCellImage:TImage, w:Int = 160, h:Int = 144 )
      
      Local temp:TTextInput = New TTextInput
      
      temp._hFont = hFont
      
      temp._hCellImage = hCellImage
      temp._iCellW = hCellImage.width
      temp._iCellH = hCellImage.height
      
      temp._sChars:String = hFont.getCharset(  )
      
      temp._w = w
      temp._h = h
      
      'Raster
      temp._iNumRows:Int = temp._sChars.length / 8 + 1
      temp._iNumCols:Int = 8
      
      temp._iCursorFrame = 1
      
      Return temp
      
   EndFunction
   
   '#Region Auswahlrechteck bei Druck animieren
   Method holdKey(  )
      
      _iCursorFrame = 2
      
   EndMethod
   
   Method releaseKEy(  )
      
      _iCursorFrame = 1
      
   EndMethod
   '#End Region

   Method getSelectedChar:String(  )
      
      Return Chr( _sChars[_iPos] )
      
   EndMethod
   
   '#Region Auswahlrechteck bewegen
   Method moveCursor( iKeyUp:Int, iKeyRight:Int, iKeyDown:Int, iKeyLeft:Int )
            
      If iKeyUp
         
         _iPos :- _iNumCols
         
      ElseIf iKeyDown
         
         _iPos :+ _iNumCols
         
      ElseIf iKeyRight
         
         _iPos :+ 1
         
      ElseIf iKeyLeft
         
         If _iPos > 0 Then _iPos :- 1
         
      EndIf
      
      'Aktuelle Position im Raster
      Local iRow:Int = _iPos / _iNumCols
      Local iCol:Int = _iPos - iRow * _iNumCols
      
      Local iD:Int = _iNumCols * _iNumRows - _sChars.length
      If iRow > _iNumRows - 1
         iRow = 0
      ElseIf _iPos = -8
         iRow = _iNumRows - 1
         'iCol = 0
      ElseIf _iPos < 0'iRow < 0
         iRow = _iNumrows
      EndIf
      If iRow = _iNumRows - 1
         If iCol > _iNumCols - iD Then iCol = _iNumCols - iD
      EndIf
      
      _iPos = iRow * _iNumCols + iCol
      
   EndMethod
   '#End Region
   
   Method draw(  )
      
      'Größe der Zellen im Raster
      Local iShownWidth:Int = _w / _iNumCols
      Local iShownHeight:Int = _iCellH + 2
      
      For Local i:Int = 0 To _sChars.length
         
         'Position im Raster
         Local iRow:Int = i / _iNumCols
         Local iCol:Int = i - iRow * _iNumCols
         
         'Position auf Bildschirm
         Local x:Int = ( iCol * iShownWidth ) + ( iShownWidth - _iCellW ) / 2
         Local y:Int = ( iRow * iShownHeight ) + _h - ( _iNumRows * iShownHeight )
         
         Local iFrame:Int = 0
         
         'Aktuelles Zeichen markiert
         If _iPos = i
            
            iFrame = _iCursorFrame
            
         EndIf
         
         DrawImage _hCellImage, x, y, iFrame
         _hFont.draw( Chr( _sChars[i] ), x + 3, y + 2 )
         
      Next
      
   EndMethod
   
EndType

Global TEXTINPUTMANAGER:TTextInputManager = New TTextINputManager
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