2010-12-29 5 views
0

Ich baue ein Spiel in C#, mit dem Sie Ihr eigenes Level skripten können, obwohl ich ein wenig überlegt habe.C# Containerklasse

Ich habe eine Basisklasse namens "Welt" als ein Objekt. Dies wurde mit einem einfachen gemacht:

class World {

Wenn jedoch der Benutzer ihr Niveau ist scripting, alle Spielobjekte werden in der Welt Objekt enthalten sein. Ich möchte sie in der Lage sein, etwas auf den Linien zu tun:

Ich weiß, dass die System.Windows.Forms.Panel und andere Klassen wie Container und Objekte in ihnen haben können und auf diese Art und Weise zugegriffen werden .. . meine Frage ist, wie kann ich eine Klasse machen, die wie ein Behälter, in dem ich Objekte, und sie dann Zugriff mit einem World.ObjectName

hinzufügen kann ich class World : System.Collections.CollectionBase versucht, aber mit dieser Methode muss ich World.Item("ObjectName") halten eingeben

Kann a Nyone Hilfe?

Danke!

Antwort

4

besten Sie tun können, ist indexer wie folgt hinzu:

public string this[string name] 
{ 
    get 
    { 
     return this.Item(name); 
    } 
} 

Item() Unter der Annahme, bereits funktioniert, und es so nennen:

string value = world["ObjectName"]; 
+0

Danke, ich habe das versucht und es funktioniert gut. Aber gibt es eine Möglichkeit, 'world.ObjectName' zu ​​machen, weil es sicher möglich ist, weil' System.Windows.Forms.Panel' es schafft! – Jamie

+0

Wenn Sie in der Entwurfszeit ein Steuerelement zu einem übergeordneten Steuerelement hinzufügen, wird dem übergeordneten Steuerelement ein Feld hinzugefügt. Dies geschieht zur Entwurfszeit - vor dem Kompilieren. Sie können dies mit Objekten mit einer langen Anwendungslebensdauer tun, aber wenn Ihre Objekte zur Laufzeit hinzugefügt werden, ist dies nicht möglich (es sei denn, Sie führen zur Laufzeit Codegenerierung und -kompilierung durch - was für diesen Fall nicht geeignet ist). –

+0

@Jamie: nicht möglich, wie andere bereits sagten. Wenn Sie es "stark typisiert" haben möchten, d. H. Eine Zeichenfolge, die Tippfehler enthalten könnte, vermeiden, können Sie in dem aufrufenden Code "enum" verwenden, z. 'string value = world [PossibleNames.ObjectName.ToString()];' –

0

Sie müssen Ihre World öffentliche Eigenschaften hinzufügen Klasse. Diese öffentlichen Eigenschaften legen private Felder dieser Klasse offen, sodass Sie sie aus Code außerhalb der Klasse selbst festlegen können.

Zum Beispiel Ihre World könnte wie folgt aussehen:

class World 
{ 
    private string _ObjectName; 

    public string ObjectName 
    { 
     get 
     { 
      return _ObjectName; 
     } 
     set 
     { 
      _ObjectName= value; 
     } 
    } 
} 

Und dann könnten Sie Code schreiben, der wie folgt aussah:

World myWorld = new World(); 
myWorld.ObjectName = "Home World"; 


Weitere Informationen lesen Sie this tutorial auf Hinzufügen von Eigenschaften zu Klassen in C# und die zuletzt aktualisierte C# Programming Guide in Bezug auf Eigenschaften.

+0

Aber würde das in IntelliSense in Visual Studio nicht nur als Eigenschaft, nicht als Objekt angezeigt? Wie würde ich das auch als dynamisch bezeichnen? Sagen wir mal, auf halbem Weg durch eine Ebene wird ein anderes Objekt zum "World" -Objekt hinzugefügt. Wie kann ich darauf mit "World.Object" als Eigenschaft zugreifen? Danke – Jamie

+0

@Jamie: Sie gaben dem Beispiel von 'System.Windows.Forms.Panel' das Verhalten, das Sie erreichen wollten. Ich bin mir nicht bewusst, dass es Eigenschaften dynamisch aussetzt. Und Sie könnten ein Objekt (jede Klasse Ihrer Wahl, benutzerdefiniert oder nicht, mit seinen * eigenen * Mitgliedern und Eigenschaften) als Eigenschaft und nicht nur als einen der Standarddatentypen verfügbar machen. –

0

Erstens, in System.Windows.Forms.Panel, System.Windows.Forms Teil ist nur der Namespace und Panel ist die Klasse.

Eine andere Möglichkeit, die Objekte in dem von Ihnen vorgeschlagenen Muster anzuzeigen, würde eintreten, wenn Sie die Klassen in Ihrer Weltklasse als static deklarieren.

class World 
     { 
      public static class ParentObject 
      { 
       public static int memberX; 
      } 
     } 

Dann können Sie sie mit dem Klassennamen als

World.ParentObject.memberX = 10; 

Aber ich immer noch glaube nicht, dass dies für Sie verwenden, um direkt eine machbare Lösung.

1

Leider ist System.Windows.Forms.Panel nicht wirklich dazu in der Lage, und Sie auch nicht. Was den Windows Forms-Fall betrifft, werden die entsprechenden Eigenschaften automatisch für eine Klasse generiert, die von Panel abgeleitet ist. Dies bedeutet, dass in der Tat Eigenschaften für die Steuerelemente benannt werden, die Sie über den Designer hinzugefügt haben. Dies basierte jedoch auf Informationen, die zur Design-/Kompilierzeit verfügbar waren. Beachten Sie, dass, wenn Sie Steuerelemente dynamisch AT RUNTIME in einer Windows Forms-Anwendung hinzufügen, keine entsprechenden Eigenschaften auf dem Panel-Objekt magisch erscheinen (obwohl auf sie über eine reguläre Auflistungsschnittstelle zugegriffen werden kann). Diese automatische Generierung von Accessoren kann den Eindruck erwecken, dass es etwas Besonderes an Panel gibt, aber das ist es wirklich nicht.

+0

Danke für die Information. Ich nehme an, dass ich den Indexer hinzufügen könnte, aber wenn Sie das Skript in meinem Spiel speichern, ersetzt es World.Object1, um es zu World ["Object1"] zu machen, also kann die Person, die den Level erstellt, World.Object1 verwenden Ausführen von World ["Object1"]. Denkst du, das ist eine gute Idee? – Jamie

+0

Jamie, kann nicht wirklich sagen, da wir nicht viel über Ihr System wissen; stellen Sie C# direkt Ihren Level-Erstellern als Skriptsprache zur Verfügung oder lassen Sie sie das Level auf andere Weise erstellen und generieren Sie nur C# -Code daraus im Hintergrund? Habe diesen Teil nicht ganz verstanden, tut mir leid. Im ersten Fall würde ich wahrscheinlich davor zurückschrecken, Code-Auto-Generierung einzuführen, da dies in der Implementierung und Wartung ziemlich teuer werden kann. Aber das ist meistens Bauchgefühl, ich glaube nicht, dass ich dazu befähigt bin, dies zu stark zu kommentieren. – ig2r

+0

Ich benutze LuaInterface, um den Level-Erschaffern Lua zu geben. Ich verwende eine einfache RegisterFunction, um eine C# -Funktion zu registrieren, die die Klasse erstellt und zurückgibt. Daher können sie Spielobjekte/Klassen in Lua erstellen. – Jamie

0

Beim Entwerfen von Form s, Panel s usw. Visual Studio generiert Code für jedes Element, das Sie in die Entwurfsansicht ziehen. Sie können diesen automatisch generierten Code in xxx.designer.cs Dateien finden. Es ist dieses Feature von Visual Studio, das Sie möchten, nicht der Formular- oder Panel-Klasse.

Sie müssten Code-Generierung durchführen (wie Shadow Wizard es formuliert), um das gleiche zu erreichen. Sonst ist es nicht möglich, zumindest in meinem Wissen.