Game Engine Math

KWEngine, Teil 13: HUD-Objekte hinzufügen

Im Gegensatz zu GameObject-Instanzen werden HUD-Objekte in 2D platziert, so dass sie sich an den tatsächlichen Pixelkoordinaten des Monitors orientieren.
HUD-Objekte können Instanzen der folgenden Klassen sein:

  • HUDObjectImage,
  • HUDObjectText und
  • HUDObjectTextInput

Sie werden idealerweise in den Prepare()-Methoden Ihrer World-Klassen hinzugefügt.

Beispiel 1: Text platzieren

public class GameWorld : World
{
    public override void Act()
    {
        HUDObjectText h = GetHUDObjectTextByName("MyHUDObject");
        
        // Wenn ein Objekt dieses Typs und dieses Namens gefunden werden
        // konnte, ist die Variable h nicht 'leer', also 'nicht null':
        if(h != null)
        {
            if(h.IsMouseCursorOnMe() == true)
            {
                h.SetColorEmissiveIntensity(1.5f);   
            }
            else
            {
                h.SetColorEmissiveIntensity(0.0f);
            }
        }
    }

    public override void Prepare()
    {
        // Platziere ein textbasiertes HUD-Objekt:
        HUDObjectText h = new HUDObjectText("Hello World!");
        h.SetPosition(64, 32);                // 64 Pixel von links und 
                                              // 32 Pixel von oben auf dem Bildschirm 
        h.Name = "MyHUDObject";               // Interner Name des Objekts, damit es später 
                                              // von anderen Objekten gefunden werden kann
        h.SetCharacterDistanceFactor(1.0f);   // Abstandsmultiplikator (der Buchstaben zueinander)
        h.SetColor(1.0f, 0.0f, 0.0f);         // Reguläre Färbung (hier: rot)
        h.SetColorEmissive(1.0f, 1.0f, 1.0f); // Glühfarbe (RGB), die Intensität wird separat geregelt
        
        AddHUDObject(h);
    }
}

Im obigen Beispiel wird ein HUDObjectText in der Variable h angelegt und mit einem anzuzeigenden Text belegt.
Anschließend wird es der aktuellen World hinzugefügt.

In der Act()-Methode wird dann mittels GetHUDObjectTextByName() nach einem HUDObjectText-Objekt dieses Namens gesucht und geprüft, ob sich der Mauszeiger gerade über dem Objekt befindet. Wenn ja, fängt das Objekt an zu glühen.

Beispiel 2: Texteingabefeld platzieren

Alternativ kann auch ein Texteingabefeld (Klasse HUDObjectTextInput) verwendet werden. Erlangt dieses Objekt den Fokus (z.B. via Mausklick), werden sämtliche Keyboardeingaben abgefangen, bis das Objekt den Fokus verliert (z.B. durch die Betätigung der ENTER- oder ESCAPE-Taste).

Wird die Eingabe abgeschlossen (z.B. durch Drücken der ENTER-/ESCAPE-Taste), löst die HUDObjectTextInput-Instanz ein WorldEvent aus. Dieses muss dann in der Methode OnWorldEvent(...) in der Welt-Klasse abgefangen werden.

public class GameWorld : World
{
    public override void Act()
    {
        HUDObjectTextInput h = GetHUDObjectTextInputByName("MyHUDObject");
        
        // Wenn ein Objekt dieses Typs und dieses Namens gefunden werden
        // konnte, ist die Variable h nicht 'leer', also 'nicht null':
        if(h != null)
        {
            if(
                h.IsMouseCursorOnMe() == true && 
                Mouse.IsButtonPressed(MouseButton.Left) == true && 
                h.HasFocus == false
            )
            {
                h.SetText("");       // vorherigen Textinhalt löschen
                h.SetColor(1, 1, 0); // Farbe zu gelb verändern
                h.GetFocus();        // Texteingabefeld erfragt den Fokus
            }
        }
    }

    public override void Prepare()
    {
        // Platziere ein textbasiertes HUD-Objekt:
        HUDObjectTextInput h = new HUDObjectTextInput("Enter your name here...");

        h.SetPosition(64, 32);                            // 64 Pixel von links und 
                                                          // 32 Pixel von oben auf dem Bildschirm 
        h.Name = "MyHUDObject";                           // Interner Name des Objekts, damit es später 
                                                          // von anderen Objekten gefunden werden kann
        h.SetColor(1.0f, 1.0f, 1.0f);                     // Reguläre Färbung (hier: weiß)      

        h.CursorBehaviour = KeyboardCursorBehaviour.Fade; // Verhalten des Eingabecursors festlegen
        
        h.CursorType = KeyboardCursorType.Underscore;     // Aussehen des Eingabecursors festlegen 
 
        AddHUDObject(h);
    }

    // Diese Methode muss immer dann implementiert werden, wenn auf ein Event
    // gewartet werden soll. 
    // Im Fall eines HUDObjectTextInput-Objekts wird immer dann ein Event
    // ausgelöst, wenn das Objekt den Fokus verliert (dies kann entweder durch
    // einen manuellen Aufruf der Instanzmethode ReleaseFocus() oder durch das
    // Abschließen oder Abbrechen der Eingabe durch die ENTER- oder ESCAPE-Taste
    // geschehen).
    protected override void OnWorldEvent(WorldEvent e)
    {
        if(e.GeneratedByInputFocusLost == true)
        {
            // Objekt erfragen, das das Event ausgelöst hat:
            // (Im Feld 'Tag' des Events befindet sich die HUDObjectTextInput-
            // Instanz, die das Event ursprünglich ausgelöst hat)
            HUDObjectTextInput h = e.Tag as HUDObjectTextInput;

            if(e.Description == "[HUDObjectTextInput|CONFIRM]")
            {
                // Wenn die Bezeichnung "CONFIRM" enthält, kann man an dieser 
                // Stelle sicher sein, dass die Eingabe erfolgreich war.   
                
                // Eingabefokus lösen:
                h.ReleaseFocus();
            }
            else if(e.Description == "[HUDObjectTextInput|ABORT]")
            {
                // Andernfalls wäre die Eingabe hier wegen eines Abbruchs
                // beendet worden.

                // Eingabefokus lösen:
                h.ReleaseFocus();
            }

            h.SetColor(1, 1, 1); // Farbe zurück auf weiß setzen
        }
    }
}

Beispiel 3: Ein Bild platzieren

public class GameWorld : World
{
    public override void Act()
    {
        HUDObjectImage h = GetHUDObjectImageByName("MyHUDObject");
        if(h != null)
        {
            if(h.IsMouseCursorOnMe() == true)
            {
                h.SetColorEmissiveIntensity(1.5f);   
            }
            else
            {
                h.SetColorEmissiveIntensity(0.0f);
            }
        }
    }

    public override void Prepare()
    {
        // Platziere ein bildbasiertes HUD-Objekt:
        HUDObject h = new HUDObjectImage("./textureFolder/myTexture.jpg");
        h.SetPosition(64f, 64f);               // Position in Pixeln (von links oben des Bildschirms aus gesehen)
        h.Name = "MyHUDObject";                // Interner Name des Objekts
        h.SetScale(128f, 128f);                // Skalierung des Bildes
        h.SetColorEmissive(1.0f, 1.0f, 1.0f);  // Glühfarbe (RGB), die Intensität wird separat geregelt

        AddHUDObject(h);
    }
}

Das Verfahren ist ähnlich zum Typ HUDObjectText, nur dass hier die Klasse HUDObjectImage verwendet wird.

Achtung:

Wenn ein neues Bild (z.B. eine JPG-Datei) dem Projekt hinzugefügt wird, muss man in den Dateieigenschaften (Rechtsklick auf die Datei im Projektmappen-Explorer gefolgt von der Auswahl des Menüpunkts „Eigenschaften“) einstellen, dass die Datei in das Ausgabeverzeichnis kopiert wird (Wert: „kopieren, wenn neuer“). Andernfalls wird die Bilddatei nicht von der Engine gefunden.


Wie finden andere Klassen (z.B. Enemy) ein HUDObject, um es anzupassen?

Im folgenden Beispiel wird nach einer HUDObjextText-Instanz gesucht. Analog dazu können aber auch die Methoden GetHUDObjectImageByName() und GetHUDObjectTextInputByName() verwendet werden.

public class Player : GameObject
{
    public override void Act()
    {
        HUDObjectText h = CurrentWorld.GetHUDObjectTextByName("the name you're looking for..");
        if(h != null)
        {
            // Hier können h jetzt Befehle erteilt werden...
        }
    }
}

Beitrag veröffentlicht

in

von

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.