Domanda

Sto sviluppando un gioco XNA.Questo è tempo che sto attento all'architettura.Fino a oggi, ho sempre implementato il mio metodo di disegni in questo modo:

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

Stavo scavando il drayambamecomponent e ho visto il metodo di disegni arriva in questo modo:

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

Prima di tutto, so che Spritebatch può raccogliere molte texture2D tra inizio e fine, in modo che possa essere utile ordinarli o disegnare con gli stessi effetti.

La mia domanda riguarda le prestazioni e il costo del passaggio dello spritebatch.A DisegabileGamecomponent è possibile chiamare Spritebatch di oggetto di gioco se il suo spritebatch è pubblico.

Cosa viene suggerito, cosa dovrebbe fare un programmatore XNA-Game?

Grazie in consiglio.

È stato utile?

Soluzione

Uno dei gravi svantaggi del DrawableGameComponent è che sei bloccato nella sua firma del metodo fornita. Mentre non c'è nulla di "sbagliato", di per sé, con DrawableGameComponent, non la pensa come " una vera architettura ". Sei meglio spento Pensando ad esso come esempio di un possibile Architettura .

Se ti trovi che devi aver bisogno di passare un SpriteBatch (o qualsiasi altra cosa) al metodo di disegno di un "componente di gioco" - il modo migliore è per passarlo come argomento . Qualsiasi altra cosa è contorta.

Ovviamente ciò significa che non è possibile utilizzare il sistema GameComponent fornito da XNA e devi creare la tua alternativa. Ma questo è quasi banali: al suo livello più elementare, è solo un elenco di qualche tipo di base che ha metodi virtuali appropriati.


.

Certo, se è necessario utilizzare GameComponent - o il tuo gioco è così semplice (ad esempio: un prototipo) che non ti importa davvero dell'architettura, quindi puoi usare fondamentalmente qualsiasi piace ottenere un SpriteBatch al tuo metodo di disegno. Hanno tutti svantaggi.

Probabilmente il metodo successivo-più architettonicamente robusto è di passare la tua istanza SpriteBatch nel costruttore di ciascuno dei tuoi componenti. Questo mantiene i tuoi componenti disaccoppiati dalla tua classe di gioco.

D'altra parte, se stai lanciando l'architettura al vento, suggerirei di rendere il tuo campo MyGame.spriteBatch public static. Questo è il modo più semplice per consentirgli accedere ovunque. È facile da implementare e facile da pulire più tardi quando / se è necessario.


.

Per rispondere alla tua domanda sulle prestazioni: qualsiasi cosa a che fare con il passaggio di un SpriteBatch in giro avrà un effetto quasi trascurabile sulle prestazioni (fornendo l'ordine delle chiamate a Draw / Begin / End rimane lo stesso). Non preoccuparti.

(Se vedi SpriteBatch whatever nel codice, che rappresenta un riferimento. Un riferimento è un valore a 32 bit (in un programma a 32 bit, che tutti i giochi XNA sono). Sono le stesse dimensioni di un int o un float generacodiDetagCode. È molto piccolo e molto economico da superare / accesso / ecc.)

Altri suggerimenti

Se sei inciampato su questa domanda probabilmente stavi guardando una soluzione piacevole e generica.Ti suggerirei di dare un'occhiata a questo:

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

Ho sentito il bisogno di correggere questa domanda perché "il modo migliore è passarlo come argomento. Qualsiasi altra cosa è contorta." è semplicemente non corretto . .

Personalmente lo sto facendo in questo modo nella mia 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);
    }
.

Ora, dal momento che stai aggiungendo disegnatoGecomponents nel metodo inizializzato della tua classe di gioco sarai in grado di chiamare

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

Direi che è l'approccio più pulito per risolvere il problema.

Se il DrawableGameComponent dovrebbe essere parte del genernario di genitore SpriteBatch, basta passare attraverso tramite il costruttore e memorizzarlo in un membro privato (o esporlo come una proprietà se lo desideri).

È possibile esporre anche il SpriteBatch come proprietà della tua classe Game se lo si desidera, come hai suggerito, ma ogni volta che hai referentato this.Game, è necessario gettarlo al tuo tipo specifico di classe Game.

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

o puoi semplicemente avere il DrawableGameComponent creare un nuovo SpriteBatch.Non c'è niente di sbagliato in questo (per quanto ho mai visto).Suppongo che dipenda da quanti DrawableGameComponents creerete e quanto spesso.

Sfoglia anche i risultati per un Cerca DrawableGameComponent - C'è un sacco di buon consiglio lì.

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top