Wie greife ich von einer anderen Klasse in XNA auf Variablen in der Game1-Klasse zu?

8

Ich versuche, eine SpriteManagerKlasse in XNA zu schreiben , benötige aber Zugriff auf die GameVariablen. Zum Beispiel Game.Contentwäre die Eigenschaft beim Laden von Texturen sehr hilfreich und Game.GraphicsDevice.Viewportbeim Abrufen der Fenstergröße.

Im Moment habe ich folgende Klasse:

public MainGame : DrawableGameComponent
{
    public SpriteManager<Enemy> EnemyManager { get; get; }
    public SpriteManager<Powerup> PowerupManager { get; set; }
    ...
}

Ich kann mir drei Möglichkeiten vorstellen, um Zugriff auf diese Variablen in der SpriteManagerKlasse zu erhalten:

  1. Lassen Sie meine Sprite-Manager-Klasse ableiten GameComponent. Dies wäre ideal, außer dass mein Sprite-Manager in verwendet wird MainGame, was a ist GameComponent.

  2. Verwenden Sie ((Game) Game1)diese Option, um auf die Variablen zuzugreifen. Diese Art der Besetzung ist jedoch hässlich und unterbricht die Kapselung.

  3. Gib alles weiter von MainGame. Beispielsweise EnemyManagermuss jedes Mal, wenn ein Feind erzeugt wird, ein zufälliger Feindtyp geladen werden. Übergeben Sie also die Eigenschaft , anstatt die Texturen zu laden MainGame, und lassen Sie sie das Laden der Textur übernehmen. Ich bin mir jedoch nicht sicher, ob dies der beste Weg ist, mit der Situation umzugehen. Ich kann meinen Finger nicht darauf legen, aber es scheint irgendwie "falsch" zu sein.EnemyManagerGame.Content

Ich könnte einige Ratschläge gebrauchen, wie dies am besten erreicht werden kann.

Daniel T.
quelle

Antworten:

3

Tun Sie das nicht - machen Sie den Sprite-Manager stattdessen zu einem Service .

BlueRaja - Danny Pflughoeft
quelle
Danke, dies ist das erste Mal, dass ich von Spielediensten gehört habe. Es sieht ähnlich aus wie die Abhängigkeitsinjektion, ist mir aber nur wenig vertraut.
Daniel T.
@ Daniel: Abhängigkeitsinjektions- und Servicecontainer sind zwei Arten der Inversion der Kontrolle . Siehe diese Antwort für weitere Details.
BlueRaja - Danny Pflughoeft
1
Jeder ist so schnell, um es zu einem Spieledienst zu machen. Es ist nicht so schlimm, es öffentlich zu machen. Sie haben nur 1
Spielinstanz
2

Eigentlich 2 # ist nicht so schlecht (Ich gehe davon aus soll Sie unten Guss von Gamebis Game1). Sie können den Typ Game1in Ihrem Konstruktor wie folgt erzwingen :

public MainGame : DrawableGameComponent
{
    public MainGame(Game1 game) : base(game) { }
}

Sie könnten sogar eine schöne Immobilie wie diese machen. Es ist immer sicher, vorausgesetzt, der Basiswert DrawableGameComponentmacht nichts undokumentiertes.

public Game1 Game1 { get { return (Game1)Game; } }

Oder wenn Sie extrem anal sein möchten, wenn Sie nicht gießen (und das ist wirklich nicht nötig ), können Sie dies tun:

public MainGame : DrawableGameComponent
{
    public MainGame(Game1 game) : base(game) { this.Game1 = game; }

    public Game1 Game1 { get; private set; }
}
Andrew Russell
quelle