Comment accéder aux variables de la classe Game1 à partir d'une autre classe de XNA?


8

J'essaie d'écrire une SpriteManagerclasse en XNA, mais j'ai besoin d'accéder aux Gamevariables. Par exemple, la Game.Contentpropriété serait très utile pour charger des textures et Game.GraphicsDevice.Viewportserait utile pour obtenir la taille de la fenêtre.

Pour l'instant, j'ai la classe suivante:

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

Je peux penser à trois façons d'accéder à ces variables dans la SpriteManagerclasse:

  1. Faire dériver ma classe de gestionnaire de sprites GameComponent. Ce serait idéal, sauf que mon gestionnaire de sprites est utilisé dans MainGame, qui est un GameComponent.

  2. Utilisez ((Game) Game1)pour accéder aux variables. Cependant, faire ce genre de distribution est moche et rompt l'encapsulation.

  3. Transmettez tout de MainGame. Par exemple, EnemyManagerdoit charger un type d'ennemi aléatoire chaque fois qu'il engendre un ennemi, donc au lieu de charger les textures MainGame, passez EnemyManagerla Game.Contentpropriété et laissez-la gérer le chargement de texture. Cependant, je ne sais pas si c'est la meilleure façon de gérer la situation. Je ne peux pas placer mon doigt dessus, mais cela semble juste «faux» d'une certaine manière.

Je pourrais utiliser quelques conseils sur la meilleure façon d'y parvenir.

Réponses:


3

Ne faites pas cela - faites plutôt du gestionnaire de sprites un service .


Merci, c'est la première fois que j'entends parler des services de jeux. Cela ressemble à l'injection de dépendance, mais je ne la connais que légèrement.
Daniel T.12

@Daniel: l'injection de dépendances et les conteneurs de service sont deux types d' inversion de contrôle . Voir cette réponse pour plus de détails.
BlueRaja - Danny Pflughoeft

1
Tout le monde est si rapide pour en faire un service de jeu. Ce n'est pas si mal de le rendre public. Vous n'avez qu'une seule instance de jeu.
Setheron

2

En fait, le n ° 2 n'est pas si mal (je suppose que vous vouliez down-cast de Gameà Game1). Vous pouvez appliquer le type étant Game1dans votre constructeur comme ceci:

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

Vous pourriez même faire une belle propriété de commodité comme celle-ci. Il sera toujours sûr, à condition que le sous DrawableGameComponent- jacent ne fasse rien de non documenté.

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

Ou si vous voulez être extrêmement anal au sujet de ne pas lancer (et il n'y a vraiment pas besoin de l'être), vous pouvez le faire:

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

    public Game1 Game1 { get; private set; }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.