¿Cómo accedo a las variables en la clase Game1 desde otra clase en XNA?

8

Estoy tratando de escribir una SpriteManagerclase en XNA, pero necesito acceso a las Gamevariables. Por ejemplo, la Game.Contentpropiedad sería muy útil para cargar texturas y Game.GraphicsDevice.Viewportsería útil para obtener el tamaño de la ventana.

Por ahora, tengo la siguiente clase:

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

Se me ocurren tres formas de acceder a estas variables en la SpriteManagerclase:

  1. Hacer que mi clase de administrador de sprites se derive de GameComponent. Esto sería ideal, excepto que se usa mi administrador de sprites MainGame, que es a GameComponent.

  2. Use ((Game) Game1)para acceder a las variables. Sin embargo, hacer este tipo de reparto es feo y rompe la encapsulación.

  3. Pase todo de abajo MainGame. Por ejemplo, EnemyManagernecesita cargar un tipo de enemigo aleatorio cada vez que genera un enemigo, así que en lugar de cargar las texturas MainGame, pasa EnemyManagerla Game.Contentpropiedad y deja que maneje la carga de texturas. Sin embargo, no estoy seguro de si esta es la mejor manera de manejar la situación. No puedo poner mi dedo sobre él, pero parece "incorrecto" de alguna manera.

Podría usar algunos consejos sobre la mejor manera de lograr esto.

Daniel T.
fuente

Respuestas:

3

No hagas eso, haz que el administrador de sprites sea un servicio .

BlueRaja - Danny Pflughoeft
fuente
Gracias, esta es la primera vez que oigo hablar de los servicios de juegos. Se parece a la inyección de dependencia, pero estoy un poco familiarizado con ella.
Daniel T.
@Daniel: La inyección de dependencia y los contenedores de servicio son dos tipos de Inversión de Control . Vea esta respuesta para más detalles.
BlueRaja - Danny Pflughoeft
1
Todos se apresuran a convertirlo en un servicio de juegos. No es tan malo hacerlo público. Solo tienes 1 instancia de juego ..
Setheron
2

En realidad, el n. ° 2 no es tan malo (supondré que querías rebajar de Gamea Game1). Puede aplicar el tipo que está Game1en su constructor de la siguiente manera:

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

Incluso podría hacer una buena propiedad de conveniencia como esta. Siempre será seguro, siempre que el subyacente DrawableGameComponentno haga nada indocumentado.

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

O si quieres ser extremadamente anal acerca de no lanzar (y realmente no hay necesidad de serlo), puedes hacer esto:

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

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