Xna Draw: Using One SpriteBatch a tutto il gioco
-
13-12-2019 - |
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.
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" -
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:
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 DrawableGameComponent
s creerete e quanto spesso.
Sfoglia anche i risultati per un Cerca DrawableGameComponent
- C'è un sacco di buon consiglio lì.