KWEngine, Teil 4: Objekte finden

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(KeyboardState ks, MouseState ms)
    {
        IReadOnlyCollection<GameObject> objects = 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(KeyboardState ks, MouseState ms)
    {
        List<GameObject> objects = CurrentWorld.GetGameObjectsByName("Beispielname");
        foreach(GameObject g in objects)
        {
            if(g is ClassA) // Typ jedes Objekts prüfen
            {
                ClassA a = (ClassA)g; // 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(KeyboardState ks, MouseState ms)
    {
        List<ClassA> objects = CurrentWorld.GetGameObjectsByName<ClassA>("Beispielname");
        foreach(ClassA a in objects)
        {
            // Hier folgen Anweisungen an die Instanz a...
        }
    }
}

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();
       _theDesiredObject.SetModel("KWCube");
       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 : World
{
    public override void Act(KeyboardState ks, MouseState ms)
    {
        if(CurrentWorld is MyGameWorld)
        {
            ClassA a = ((MyGameWorld)CurrentWorld).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 : World
{
    public override void Act(KeyboardState ks, MouseState ms)
    {
        HUDObject h = CurrentWorld.GetHUDObjectByName("Health");
        if(h != null)
        {
            // Sende Befehle an die Instanz h...
        }
    }
}
b) Die Welt nach einem Lichtobjekt fragen
public class AnyClass : World
{
    public override void Act(KeyboardState ks, MouseState ms)
    {
        LightObject l = CurrentWorld.GetLightObjectByName("Player Flashlight");
        if(l != null)
        {
            // Sende Befehle an die Instanz l...
        }
    }
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.