Question

Je développe un jeu XNA.Il est temps que je fasse attention à l’architecture.Jusqu'à aujourd'hui, j'ai toujours implémenté ma propre méthode de dessin de cette manière :

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

Je creusais le DrawableGameComponent et j'ai vu que la méthode Draw se présentait de cette manière :

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

Tout d'abord, je sais que SpriteBatch peut collecter de nombreuses Texture2D entre Begin et End, ce qui peut être utile pour les trier, ou dessiner avec les mêmes effets.

Ma question concerne les performances et le coût de réussite du SpriteBatch.Chez DrawableGameComponent, il est possible d'appeler spritebatch d'un objet de jeu si son spritebatch est public.

Qu'est-ce qui est suggéré, que doit faire un programmeur de jeux Xna ?

Merci en conseil.

Était-ce utile?

La solution

L'un des graves inconvénients de DrawableGameComponent c'est que vous êtes enfermé dans la signature de méthode fournie.Bien qu'il n'y ait rien de "mal" en soi avec DrawableGameComponent, ne le considérez pas comme le "une véritable architecture".Tu es mieux en pensant à cela comme un exemple de possible architecture.

Si vous devez passer un SpriteBatch (ou toute autre chose) à la méthode draw d'un "composant de jeu" - la meilleure façon est le passer comme argument.Tout le reste est compliqué.

Évidemment, cela signifie que vous ne pouvez pas utiliser les fonctionnalités fournies par XNA. GameComponent système, et vous devez faire votre propre alternative.Mais c'est presque trivial :À son niveau le plus élémentaire, il s'agit simplement d'une liste d'un type de base doté des méthodes virtuelles appropriées.


Bien sûr, si vous devez utiliser GameComponent - soit ton jeu est tellement simple (ex:un prototype) dont vous ne vous souciez pas vraiment de l'architecture - alors vous pouvez l'utiliser en gros n'importe lequel méthode que vous aimez pour obtenir un SpriteBatch à votre méthode de dessin.Ils ont tous des inconvénients.

La méthode suivante la plus robuste sur le plan architectural consiste probablement à transmettre votre SpriteBatch instance dans le constructeur de chacun de vos composants.Cela maintient vos composants découplés de votre classe de jeu.

D'un autre côté, si vous jetez l'architecture au vent, je vous suggère de faire de votre MyGame.spriteBatch champ public static.C’est le moyen le plus simple de permettre d’y accéder n’importe où.Il est facile à mettre en œuvre et facile à nettoyer plus tard quand/si vous en avez besoin.


Pour répondre à votre question sur les performances :Tout ce qui a à voir avec le passage d'un SpriteBatch autour aura un effet presque négligeable sur les performances (en fournissant l'ordre des appels à Draw/Begin/End reste le même).Ne vous inquiétez pas.

(Si tu vois SpriteBatch whatever dans le code, cela représente une référence.Une référence est une valeur 32 bits (dans un programme 32 bits, ce que sont tous les jeux XNA).C'est la même taille qu'un int ou un float.C'est très petit et très bon marché à faire circuler/accéder/etc.)

Autres conseils

Si vous avez trébuché sur cette question, vous regardiez probablement une solution agréable et générique.Je vous suggère de regarder cela:

https://gamedev.stackexchange.com/questions/14217/several-classes-need-a-access-the-same-data-where-shavouler-thould-thould-Data-be-declared/14232#14232

J'ai ressenti la nécessité de corriger cette question car "Le meilleur moyen est de le transmettre comme un argument. Tout ce que c'est compliqué." est tout simplement pas correct ./ p>

Personnellement, je le fais maintenant de cette façon dans ma classe de jeu de jeu:

    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);
    }

Maintenant, puisque vous ajoutez des éventailgamecomponents dans la méthode d'initialisation de votre classe de jeu, vous pourrez appeler

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

Je dirais que c'est l'approche la plus propre pour résoudre le problème.

Si la DrawableGameComponent devrait faire partie de la vie des parents SpriteBatch, puis transmettez-le simplement via le constructeur et stockez-le dans un membre privé (ou exposez-le en tant que propriété si vous le souhaitez).

Vous pourriez également exposer le SpriteBatch comme propriété de votre Game cours si vous le vouliez, comme vous l'avez suggéré, mais à chaque fois que vous faisiez référence this.Game, vous devrez le convertir en votre spécifique Game type de classe.

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

Ou vous pouvez simplement avoir le DrawableGameComponent créer un nouveau SpriteBatch.Il n'y a rien de mal à cela (pour autant que je l'aie jamais vu).Je suppose que ça dépend du nombre DrawableGameComponents vous allez créer et à quelle fréquence.

Parcourez également les résultats pour un Rechercher DrawableGameComponent - il y a beaucoup de bons conseils là-bas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top