Como acessar variáveis ​​na classe Game1 de outra classe no XNA?

8

Estou tentando escrever uma SpriteManagerclasse no XNA, mas preciso acessar as Gamevariáveis. Por exemplo, a Game.Contentpropriedade seria muito útil para carregar texturas e Game.GraphicsDevice.Viewportpara obter o tamanho da janela.

Por enquanto, tenho a seguinte classe:

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

Eu posso pensar em três maneiras de obter acesso a essas variáveis ​​na SpriteManagerclasse:

  1. Faça minha classe de gerente de sprite derivar GameComponent. Isso seria ideal, exceto que meu gerente de sprite é usado MainGame, que é a GameComponent.

  2. Use ((Game) Game1)para acessar as variáveis. No entanto, fazer esse tipo de elenco é feio e quebra o encapsulamento.

  3. Passe tudo para baixo MainGame. Por exemplo, EnemyManagerprecisa carregar um tipo de inimigo aleatório toda vez que gera um inimigo; portanto, em vez de carregar as texturas MainGame, passe EnemyManagera Game.Contentpropriedade e deixe-a lidar com o carregamento de textura. No entanto, não tenho certeza se essa é a melhor maneira de lidar com a situação. Não consigo colocar meu dedo nele, mas parece 'errado' de alguma forma.

Eu poderia usar alguns conselhos sobre a melhor maneira de conseguir isso.

Daniel T.
fonte

Respostas:

3

Não faça isso - torne o gerente do sprite um serviço .

BlueRaja - Danny Pflughoeft
fonte
Obrigado, esta é a primeira vez que ouvi falar de serviços de jogos. Parece semelhante à injeção de dependência, mas eu estou apenas um pouco familiarizado com ela.
Daniel T.
@ Daniel: Injeção de dependência e contêineres de serviço são dois tipos de Inversão de controle . Veja esta resposta para mais detalhes.
BlueRaja - Danny Pflughoeft
11
Todo mundo é tão rápido em torná-lo um serviço de jogo. Não é tão ruim torná-lo público. Você só tem 1 instância de jogo ..
Setheron 9/09/11
2

Na verdade, o número 2 não é tão ruim (presumo que você pretendia fazer o down-cast de Gamepara Game1). Você pode impor o tipo que está Game1no seu construtor da seguinte maneira:

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

Você pode até fazer uma propriedade de conveniência agradável como esta. Sempre será seguro, desde que o subjacente DrawableGameComponentnão faça nada indocumentado.

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

Ou se você quiser ser extremamente anal sobre não transmitir (e realmente não há necessidade ), você pode fazer o seguinte:

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

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