Pergunta

Estou desenvolvendo um jogo XNA.É hora de ter cuidado com a arquitetura.Até hoje, sempre implementei meu próprio método de desenho desta forma:

public void Draw(SpriteBatch sb, GameTime gameTime)
{
    sb.Begin();
    // ... to draw ...
    sb.End();
}

Eu estava pesquisando o DrawableGameComponent e vi que o método Draw vem desta forma:

public void Draw(GameTime gameTime)
{
    // ...
}

Primeiro de tudo, eu sei que SpriteBatch pode coletar muitos Texture2D entre Begin e End, então pode ser útil classificá-los ou desenhar com os mesmos efeitos.

Minha dúvida é sobre o desempenho e o custo de aprovação no SpriteBatch.Em DrawableGameComponent é possível chamar spritebatch do objeto do jogo se seu spritebatch for público.

O que é sugerido, o que um programador de jogos xna deve fazer?

Obrigado em conselhos.

Foi útil?

Solução

Uma das sérias desvantagens DrawableGameComponent é que você está bloqueado na assinatura do método fornecido.Embora não haja nada de “errado”, por si só, com DrawableGameComponent, não pense nisso como o "uma verdadeira arquitetura".Você é melhor pensando nisso como um exemplo de uma possível arquitetura.

Se você precisar passar por um SpriteBatch (ou qualquer outra coisa) ao método draw de um "componente do jogo" - a melhor maneira é para passá-lo como um argumento.Qualquer outra coisa é complicada.

Obviamente, isso significa que você não pode usar os recursos fornecidos pelo XNA GameComponent sistema, e você tem que fazer sua própria alternativa.Mas isso é quase trivial:Em seu nível mais básico, é apenas uma lista de algum tipo base que possui métodos virtuais apropriados.


Claro, se você precisar usar GameComponent - ou seu jogo é tão simples (por exemplo:um protótipo) que você realmente não se importa com a arquitetura - então você pode usar basicamente qualquer método que você gosta de obter um SpriteBatch ao seu método de desenho.Todos eles têm desvantagens.

Provavelmente o próximo método arquitetonicamente mais robusto é passar seu SpriteBatch instância no construtor de cada um dos seus componentes.Isso mantém seus componentes desacoplados da sua classe de jogo.

Por outro lado, se você está jogando a arquitetura ao vento, sugiro que faça o seu MyGame.spriteBatch campo public static.Esta é a maneira mais simples de permitir que ele seja acessado em qualquer lugar.É fácil de implementar e limpar mais tarde, quando/se necessário.


Para responder à sua pergunta sobre desempenho:Qualquer coisa que tenha a ver com passar um SpriteBatch ao redor terá um efeito quase insignificante no desempenho (fornecendo a ordem das chamadas para Draw/Begin/End continua o mesmo).Não se preocupe com isso.

(Se você ver SpriteBatch whatever no código, isso representa uma referência.Uma referência é um valor de 32 bits (em um programa de 32 bits, como são todos os jogos XNA).É do mesmo tamanho de um int ou um float.É muito pequeno e muito barato para circular/acessar/etc.)

Outras dicas

Se você se deparou com essa questão, provavelmente estava procurando uma solução agradável e genérica.Eu sugiro que você dê uma olhada nisso:

https://gamedev.stackexchange.com/questions/14217/several-classes-need-to-access-the-same-data-where-should-the-data-be-declared/14232#14232

Senti a necessidade de corrigir esta questão porque "a melhor maneira é passar isso como um argumento.Qualquer outra coisa é complicada." e simples incorreto.

Pessoalmente, agora estou fazendo assim na minha classe GameBase:

    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        SpriteBatch = new SpriteBatch(GraphicsDevice);
        this.Services.AddService(typeof(SpriteBatch), SpriteBatch);
    }

Agora, como você está adicionando DrawableGameComponents no método Initialize da sua classe Game, você poderá chamar

    this.Game.Services.GetService(typeof(SpriteBatch))

Eu diria que essa é a abordagem mais limpa para resolver o problema.

Se o DrawableGameComponent deveria fazer parte dos pais SpriteBatch, basta passá-lo por meio do construtor e armazená-lo em um membro privado (ou expô-lo como uma propriedade, se desejar).

Você também pode expor o SpriteBatch como propriedade sua Game class se você quiser, como você sugeriu, mas toda vez que você referenciou this.Game, você precisaria lançá-lo para seu específico Game tipo de classe.

((MyGame)this.Game).SpriteBatch.Draw(...)

Ou você pode simplesmente ter o DrawableGameComponent crie um novo SpriteBatch.Não há nada de errado com isso (até onde eu já vi).Suponho que depende de quantos DrawableGameComponento que você criará e com que frequência.

Navegue também pelos resultados para um procurar DrawableGameComponent - há muitos bons conselhos aí.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top