Game Engine Math

KWEngine, Teil 4: Objekte in der Welt wiederfinden

Die Welt-Klasse als Anlaufstelle

In KWEngine dienen die Welt-Klassen als Dreh- und Angelpunkt für die meisten Interaktionen zwischen den Objekten. Sollte also ein Objekt B auf ein Objekt A zugreifen wollen, sollte es die aktuelle Welt mit der Suche beauftragen.

1) Der einfache aber langsame Weg

a) Eine Liste aller GameObject-Instanzen abrufen
public class ClassB : GameObject
{
    public override void Act()
    {
        IReadOnlyCollection<GameObject> objects = KWEngine.CurrentWorld.GetGameObjects();
        foreach(GameObject g in objects)
        {
            // Durchlaufe die Liste und suche nach dem gewünschten 
            // Objekt anhand bestimmter Merkmale (z.B. dem Namen).
        }
    }
}
b) Eine Liste aller GameObject-Instanzen mit einem bestimmten Namen
public class ClassB : GameObject
{
    public override void Act()
    {
        List<GameObject> objects = KWEngine.CurrentWorld.GetGameObjectsByName("Beispielname");
        foreach(GameObject g in objects)
        {
            if(g is ClassA) // Typ jedes Objekts prüfen
            {
                ClassA a = g as ClassA; // Expliziter type-cast nach 'ClassA'
                // Hier folgen Anweisungen an die Instanz a...
            }
        }
    }
}
c) Eine Liste aller GameObject-Instanzen mit einem bestimmten Namen und einem bestimmten Typ erfragen
public class ClassB : GameObject
{
    public override void Act()
    {
        List<ClassA> objects = KWEngine.CurrentWorld.GetGameObjectsByName<ClassA>("Beispielname");
        foreach(ClassA a in objects)
        {
            // Hier folgen Anweisungen an die Instanz a...
        }
    }
}
d) Eine Liste aller GameObject-Instanzen eines bestimmten Typs erfragen
public class ClassB : GameObject
{
    public override void Act()
    {
        List<ClassA> objects = KWEngine.CurrentWorld.GetGameObjectsByType<ClassA>();
        foreach(ClassA a in objects)
        {
            // Hier folgen Anweisungen an die jeweilige Instanz a...
        }
    }
}
f) genau ein Objekt eines bestimmten Typs mit einem bestimmten Namen erfragen
public class ClassB : GameObject
{
    public override void Act()
    {
        ClassA instanceOfA= KWEngine.CurrentWorld.GetGameObjectByName<ClassA>("Beispielname");
        if(instanceOfA != null)
        {
            // Hier folgen Anweisungen an die gefundene Instanz...
        }
    }
}

2) Der performante aber dafür umständlichere Weg

Die in Abschnitt 1) beschriebenen Möglichkeiten sind einfach zu benutzen, durchsuchen aber bei jedem Aufruf die gesamte Liste der in der Welt aktiven GameObject-Instanzen. Bei vielen gleichzeitig aktiven Instanzen kann sich dies negativ auf die Performance auswirken.

Schritt a) Ein oft verwendetes Objekt in der Welt öffentlich machen
public class MyGameWorld : World
{
    private ClassA _theDesiredObject;

    public override void Prepare()
    {
       _theDesiredObject= new ClassA();
       AddGameObject(_theDesiredObject);
    }

    public ClassA GetTheDesiredObject()
    {
        return _theDesiredObject;
    }
}

In der Welt-Klasse wird ein bestimmtes Objekt der Klasse A als privates Feld deklariert und erhält eine öffentliche Get-Methode, die von jedem anderen Objekt aufgerufen werden kann. So können andere Objekte sich an die Welt wenden und diese direkt um das gesuchte Objekt bitten statt eine ganze Liste von Objekten durchsuchen (lassen) zu müssen!

Schritt b) Die aktuelle Welt direkt nach diesem Objekt fragen
public class ClassB : GameObject
{
    public override void Act()
    {
        if(CurrentWorld is MyGameWorld)
        {
            ClassA a = (CurrentWorld as MyGameWorld).GetTheDesiredObject();
            // Hier können dann Befehle an Objekt a folgen!
        }
    }
}

Jetzt muss z.B. ein Objekt der Klasse B nur noch die aktuelle Welt fragen, ob sie gerade der Klasse MyGameWorld entstammt. Wenn ja, wird die aktuelle Welt-Instanz explizit nach MyGameWorld gecastet und die darin befindliche Get-Methode aufgerufen.


Gleiches gilt für Licht- und HUD-Objekte

a) Die Welt nach einem HUD-Objekt fragen
public class AnyClass : GameObject
{
    public override void Act()
    {
        HUDObjectText h = KWEngine.CurrentWorld.GetHUDObjectTextByName("Health");
        if(h != null)
        {
            // Sende Befehle an die Instanz h...
        }
        else
        {
            // HUDObject-Instanz mit diesem Namen nicht gefunden...
        }
    }
}
b) Die Welt nach einem Lichtobjekt fragen
public class AnyClass : GameObject
{
    public override void Act()
    {
        LightObject l = KWEngine.CurrentWorld.GetLightObjectByName("Player Flashlight");
        if(l != null)
        {
            // Sende Befehle an die Instanz l...
        }
    }
}

Beitrag veröffentlicht

in

von

Schlagwörter:

Kommentare

Schreibe einen Kommentar

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

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.