Animierte scrollende Textbox

Übersicht BlitzMax, BlitzMax NG Codearchiv & Module

Neue Antwort erstellen

DivineDominion

Betreff: Animierte scrollende Textbox

BeitragMo, Mai 16, 2005 19:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist zum animierten anzeigen von Textboxen gedacht, für meine QuickRPG-Projekte, die ich wieder aufgreife. Das Beispielbild ist für ein 3-Farben-Spiel (GameBoy) gewesen, aber da ist mir das mit der Grafik zu kompliziert und daher lege ich das erstmal auf Eis Smile

Man muss vor der Mainloop einmal folgende Zeilen aufrufen:
Code: [AUSKLAPPEN]

hFont:TFontImage = TFontImage.load( "font.png", 8, 8, "font.txt" ) 'Link siehe unten
TEXTBOXMANAGER.init( hFont, "textbox.png" )


Man muss ggf. den Aufruf von genTextboxImage() anpassen, da die Breite auf 160 Pixel eingestellt ist, was für den GameBoy-Screen gedacht war, oder eben die Standartbreite verändern.


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

bmx: http://divinedominion.art-fx.o...extbox.bmx
Bild: http://divinedominion.art-fx.o...extbox.png

Code: [AUSKLAPPEN]
Strict

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

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


'Stadien die die Textbox hat
Const TEXTBOX_NONE = 0
Const TEXTBOX_PROCESS = 1
Const TEXTBOX_CLOSE = -1

Type TTextboxManager
   
   Rem
      Für neue Textboxen wird das Bild und
      die Standartschrift einmal bei init()
      festgelegt und später weiterverwendet.
   EndRem
   Field _hTextboxImage:TImage
   Field _hFont:TFontImage
   
   'Textbox selber
   Field _hTextbox:TTextbox
   
   'Status der Textbox
   Field _iTextboxStatus:Int
   
   'Höhe des Arbeitsschirmes (Für Ausrichtung)
   Field _iScreenHeight:Int
   
   
   Method init(hFont:TFontImage, sFile:String, iLines:Int = 3, iWidth:Int = 160, iFrameSize = 8, iFrameCount = 15, iScreenHeight:Int = 144 )
      _hFont = hFont
      
      _hTextboxImage = CreateImage( iWidth, ..
         ( iLines + 2 ) * iFrameSize, ..
         3, ..
         DYNAMICIMAGE | MASKEDIMAGE )
      
      _iScreenHeight = iScreenHeight
      
      genTextboxImage( _hTextboxImage, ..
         LoadAnimImage( sFile, iFrameSize, iFrameSize, 0, iFramecount ), ..
         iLines, ..
         iFrameSize, ..
         iWidth )
         
   EndMethod
   
   Method getStatus:Int(  )
      
      Return _iTextboxStatus
      
   EndMethod
   
   Method handleTextbox:Int( iKeyState:Int )
      
      'Standartstatus - keiner
      _iTextboxStatus = TEXTBOX_NONE
      
      'Ggf. vorhandene Textbox bearbeiten
      If _hTextbox
         
         'Events behandeln
         _hTextbox.handleEvents(  )
         
         '-> Status auf "arbeit" setzen
         _iTextboxStatus = TEXTBOX_PROCESS
         
         
         'Auf Tastendruck reagieren
         If iKeyState = KEY_STATE_HIT
            
            'Reaktion auf Tastendruck: Scrollen oder Schließen
            Local iAction = _hTextbox.getAction(  )
            
            If iAction = TEXTBOX_SCROLL
               
               _hTextbox.scroll
               
            ElseIf iAction = TEXTBOX_EXIT
               
               _hTextbox = Null
               
               'Status auf "schließen" setzen
               _iTextboxStatus = TEXTBOX_CLOSE
               
            EndIf
            
         EndIf   
         
      EndIf
      
   EndMethod
   
   'Ggf. aktuelle Textbox malen
   Method draw(  )
      
      If _hTextbox
         
         _hTextbox.draw
         
      EndIf
      
   EndMethod
   
   'Textbox erstellen
   Method startDialogue( sText:String, iPos:Int )
      
      _hTextbox = TTextbox.create( sText, _hTextboxImage, _hFont, iPos, _iScreenHeight )
      
   EndMethod
   
EndType

'Position der Textbox (oben/unten ausgerichtet)
Const TEXTBOX_TOP = 0
Const TEXTBOX_BOTTOM = 1

'Aktionen die eine Textbox ausführt
Const TEXTBOX_NORMAL = 0
Const TEXTBOX_SCROLL = 1
Const TEXTBOX_EXIT = 2

Type TTextbox
   
   'Ausgerichtete Position (oben/unten)
   Field _pos:Int
   
   'Bild der Box
   Field _image:TImage
   
   'Schrift für den Text
   Field _font:TFontImage
   
   'zum berechnen die Arbeitsbildschirmhöhe
   Field _iScreenHeight:Int
   
   '#Region Text
   
   Field _text:String[], _textLines:Int
   
   Field _height:Int
   
   'Text scrollen?
   Field _textScroll:Int
   'Zeilen die noch gescrollt werden muss bis zum Halt
   Field _textScrollLeft:Int
   
   'Momentane Zeile und Spalte im Text
   Field _textRow:Int, _textCol:Int
   
   'Zeichenanimation timen
   Field _textTimer:Int
   
   '#End Region
   
   '#Region Aktion
   
   'Aktionsart
   Field _action:Int = TEXTBOX_NORMAL, _blink:Int
   
   'Timer fürs Blinken
   Field _actionTimer:Int
   
   '#End Region
   
   Function create:TTextbox( sText:String, hImage:TImage, hFont:TFontImage, iPos:Int = TEXTBOX_TOP, iScreenHeight:Int = 144)
      
      Local temp:TTextbox = New TTextbox
      
      'Werte übernehmen
      temp._pos = iPos
      
      temp._image = hImage
      
      temp._font = hFont
      
      temp._iScreenHeight = iScreenHeight
      
      temp._height = 3
      
      'Maximale Zeichenlänge pro Zeile
      Local iMaxChars:Int = 160 / 8 - 2
      
      'Liste für Textparsing
      Local hList:TList = CreateList(  )
      
      'Leerzeichen drumrum entfernen
      sText.Trim
         
      While sText.length > 0

         'Position des letzten passenden Leerzeichens rausfinden
         Local iPos:Int, iNewPos:Int
         Repeat
            
            iPos = iNewPos
            iNewPos = sText.find( " ", iPos + 1)
            
         Until iNewPos > iMaxChars Or iNewPos = -1
         
         'Wenn Zeichenlänge kleiner als Zeilenlänge, alles nehmen
         If sText.length < iMaxChars Then iPos = sText.length
         
         Local sLine:String = sText[..iPos]'Left( sText, iPos )
         sText = sText[sText.length - ( sText.length - iPos - 1)..]'Right( sText, sText.length - iPos - 1 )
         
         'String hinzufügen
         hList.addLast(sLine)
         
      Wend
      
      'Maximal 3 Zeilen bis Scrollaufforderung
      temp._textLines = hList.count()
      temp._textScrollLeft = temp._textLines
      If temp._textScrollLeft > temp._height Then temp._textScrollLeft = temp._height
      
      'Liste umwandeln
      temp._text = New String[hList.count()]
      Local i:Int = 0
      For Local sLine:String = EachIn hList
         temp._text[i] = sLine
         i:+1
      Next      
      'temp._text = String[]( hList.toArray(  ) )
      
      'Liste löschen
      hList.clear
      hList = Null
      
      Return temp

   EndFunction
   
   '#Region Anzeigen jeglichen Inhalts der Box
   Method draw(  )
      
      Self.drawBox
      Self.DrawText
      
   EndMethod
   
   Method drawBox(  )
      
      Local y:Int = Self.giveY(  )      
      
      Local iFrame:Int
      
      If Self._action = TEXTBOX_NORMAL
         
         iFrame = 0
         
      Else
         
         If Self._blink
            
            iFrame = 0
            
         Else
            
            If Self._action = TEXTBOX_SCROLL
               
               iFrame = 1
               
            ElseIf Self._action = TEXTBOX_EXIT
               
               iFrame = 2
               
            EndIf
         
         EndIf
         
      EndIf
      
      DrawImage Self._image, 0, y, iFrame
      
   EndMethod
   
   Method DrawText(  )
      
      Local iLine:Int = 0
      
      Local y:Int = Self.giveY(  ) + 8
      
      For Local sLine:String = EachIn Self._text
         
         Local drawY:Int = y + 8 * iLine
         If iLine = Self._textRow
            'Aktuelle Zeile (muss noch animiert werden)
            
            'Self._font.draw( Left( sLine, Self._textCol ), 8, drawY )
            Self._font.draw( sLine[..Self._textCol], 8, drawY )
            
            'Schleife beenden
            Exit
            
         Else
            'Fertige Zeilen
            
            Self._font.draw( sLine, 8, drawY )
            
         EndIf
         
         iLine :+ 1
            
      Next
      
   EndMethod
   '#End Region
   
   '#Region Ereignisse bearbeiten
   Method handleEvents(  )
      
      '#Region Text animiert anzeigen (TEXTBOX_NORMAL)
      If Self._action = TEXTBOX_NORMAL
         
         Rem
            Der Timer für die Animimation
            des nächsten Buchstabens muss
            abgelaufen sein, bevor überhaupt
            etwas passiert.
         EndRem
         If MilliSecs(  ) > Self._textTimer
            
            'Cursor verschieben
            Self.showNextChar
            
            'Eventuell zur nächsten Zeile springen
            Self.changeRow
            
            'Ggf. Status ändern
            Self.changeStatus
            
            
            'Timer neu setzen            
            Self._textTimer = MilliSecs(  ) + 100
            
         EndIf
         
      EndIf
      '#End Region
      
      'Bei Aktionen blinken lassen
      Self.blink(  )
      
   EndMethod
   
   Method showNextChar(  )
      
      'Nächstes Zeichen (Cursor nach rechts)
      Self._textCol :+ 1
      
      Rem
         Leerzeichen überspringen, wenn das aktuelle
         Zeichen (bzw. auch die danach) Leerzeichen
         sind.
      EndRem
      While Chr( Self._text[Self._textRow][Self._textCol] ) = " "

         
         Self._textCol :+ 1
         
      Wend
            
   EndMethod
   
   Method changeRow(  )
      
      Rem
         Wenn der Cursor die Zeilenlänge überschreitet,
         wird die zu animierende Zeile gewechselt.
      EndRem
      If Self._textCol > Self._text[Self._textRow].length
         
         'Cursor zurücksetzen
         Self._textCol = 0
         
         'Nächste Zeile
         Self._textRow :+ 1
         
         'Zeilen bis zur nächsten Scrollaufforderung
         Self._textScrollLeft :- 1
         
         Rem
            Wenn gescrollt wird, wird die jeweils oberste
            Zeile aus dem Stringarray entfernt, weil unten
            eine neue dran kommt.
         EndRem
         If Self._textScroll And Self._textScrollLeft
            
            Self._text = Self._text[1..]
            Self._textRow :- 1
            
         EndIf
         
      EndIf
            
   EndMethod
   
   Method changeStatus(  )
      
      Rem
         Wenn alle neuen Zeilen angezeigt wurden,
         wird der Status der Box gewechselt.
      EndRem
      If Self._textScrollLeft = 0
         
         'Wenn keine Zeilen übrig sind, beenden
         If Self._textLines <= Self._height
         
            Self._action = TEXTBOX_EXIT
         
         Else
            
            Self._action = TEXTBOX_SCROLL
         
         EndIf
         
      EndIf
      
   EndMethod

   Method blink(  )
      
      If Self._action <> TEXTBOX_NORMAL
         
         'Blinken des Symbols
         If MilliSecs(  ) > Self._actionTimer
            
            Self._blink = Not Self._blink
            Self._actionTimer = MilliSecs(  ) + 500
            
         EndIf
         
      EndIf
      
   EndMethod
   '#End Region
   
   'Text weiter anzeigen
   Method scroll(  )
      
      'Anzahl an übrigen Zeilen verringern
      Self._textLines :- Self._height
      
      'Scrollen anschalten
      Self._textScroll = True
      
      'Rest des Textes, aber MAXIMAL 3 ZEILEN, scrollen
      Self._textScrollLeft = Self._textLines
      If Self._textScrollLeft > Self._height Then Self._textScrollLeft = Self._height
      
      'Oberste Zeile abschneiden
      Self._text = Self._text[1..]
      Self._textRow :- 1
      
      'Aktion zurücksetzen
      Self._action = TEXTBOX_NORMAL
      
   EndMethod
   
   Method giveY:Int(  )
      
      Local y:Int
      
      Select Self._pos
         Case TEXTBOX_TOP
            y = 0
         Case TEXTBOX_BOTTOM
            y = Self._iScreenHeight - Self._image.height
      EndSelect
      
      Return y
      
   EndMethod   
   
   Method getAction:Int(  )
      
      Return Self._action
      
   EndMethod
   
EndType

'Textboxtaugliches bild erstellen
Function genTextboxImage( dest:TImage Var, hImage:TImage, iRows:Int = 3, iFrameSize:Int = 8, iWidth:Int = 160 )
   
   Rem
      011111111112
      3          5
      677777779A78
              BC
              DE
   EndRem
   
   Local h:Int = ( iRows + 2 ) * 8
   Local w:Int = iWidth
   
   'Ecken
   DrawImage hImage, 0, 0, 0
   DrawImage hImage, w - iFrameSize, 0, 2
   DrawImage hImage, 0, h - iFrameSize, 6
   DrawImage hImage, w - iFrameSize, h - iFrameSize, 8
   
   For Local i:Int = 0 To iRows + 1
      
      Local iFrame:Int
      
      If i = 0
         'Oben
         
         iFrame = 1
      
      ElseIf i = iRows + 1
         'Unten
         
         iFrame = 7
      
      Else
         'Textfläche
         
         iFrame = 4
         
         'Links & rechts Rand malen
         
         DrawImage hImage, 0, i * iFrameSize, 3
         DrawImage hImage, w - iFrameSize, i * iFrameSize, 5
         
      EndIf
      
      'Zeile füllen
      For Local x:Int = 1 To (iWidth / iFrameSize - 2)
         
         DrawImage hImage, x * iFrameSize, i * iFrameSize, iFrame
         
      Next
      
   Next
   
   'Aktionsblock
   DrawImage hImage, 134, h - iFrameSize, 9
   DrawImage hImage, 142, h - iFrameSize, 10
   
   GrabImage dest, 0, 0, 0
   
   DrawImage hImage, 134, 32, 11
   DrawImage hImage, 142, 32, 12
   
   GrabImage dest, 0, 0, 1
   
   DrawImage hImage, 134, 32, 13
   DrawImage hImage, 142, 32, 14
   
   GrabImage dest, 0, 0, 2
   
EndFunction

Global TEXTBOXMANAGER:TTextboxManager = New TTextboxManager


Edit: Hat sich wohl was geändert in 1.09 - hList.toArray() funzt nimmer wie geplant.
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