Question

Je n'ai pas programmé de jeux depuis environ 10 ans (ma dernière expérience était DJGPP + Allegro), mais je pensais que je verrais XNA ce week-end pour voir comment cela se préparait.

Je suis assez impressionné. Cependant, alors que je continue à assembler un moteur de jeu, j'ai une question (probablement) fondamentale.

À quel point devriez-vous compter sur les délégués et les événements de C # pour piloter le jeu? En tant que programmeur d’application, j’utilise beaucoup les délégués et les événements, mais je ne sais pas s’il ya une surcharge à faire.

Dans mon moteur de jeu, j'ai conçu une "caméra de poursuite". de sortes, qui peuvent être attachés à un objet et ensuite recalculer sa position par rapport à l'objet. Lorsque l'objet se déplace, il existe deux façons de mettre à jour la caméra de poursuite.

  • disposer d'un "UpdateCameras ()" méthode dans la boucle principale du jeu.
  • Utilisez un gestionnaire d'événements et demandez à la caméra de chasse de s'abonner à object.OnMoved.

J'utilise ce dernier moyen, car il me permet d'enchaîner des événements et d'automatiser de manière élégante de grandes parties du moteur. Tout à coup, ce qui serait énorme et complexe serait abandonné à une poignée de gestionnaires d’événements de 3 à 5 lignes ... C’est une beauté.

Toutefois, si les gestionnaires d'événements déclenchant toutes les nanosecondes s'avèrent être un ralentissement majeur, je les supprime et j'utilise l'approche en boucle.

Des idées?

Était-ce utile?

La solution

Si vous envisagiez un événement comme une liste d'abonnés, dans votre code, vous ne faites qu'inscrire un abonné. Le nombre d’instructions nécessaires pour atteindre cet objectif sera probablement minime au niveau du CLR.

Si vous souhaitez que votre code soit générique ou dynamique, vous devez vérifier si quelque chose est souscrit avant d'appeler un événement. Le mécanisme événement / délégué de C # et .NET vous le fournit à très peu de frais (en termes de processeur).

Si vous êtes vraiment préoccupé par chaque cycle d'horloge, vous n'écrirez jamais de logique de jeu générique / dynamique. C'est un compromis entre le code maintenable / configurable et la vitesse réelle.

Bien écrit, je privilégierais les événements / délégués jusqu'à ce que je puisse prouver que c'est un problème.

Le seul moyen de savoir si cela vous pose problème est de profiler votre code - ce que vous devriez faire de toute façon pour tout développement de jeu!

Autres conseils

Il est important de comprendre que les événements en C # ne sont pas des événements asynchrones en file d'attente (comme, par exemple, la file d'attente de messages Windows). Ils sont essentiellement une liste de pointeurs de fonction. Donc, déclencher un événement n'a pas de pire impact sur les performances que de parcourir une liste d'indicateurs de fonctions et d'appeler chacun d'entre eux.

Dans le même temps, sachez que, de ce fait, les événements sont synchrones. Si votre écouteur est lent, vous ralentissez la classe en levant les événements.

La principale question ici semble être: "Quels sont les frais généraux associés à l'utilisation de délégués et d'événements C #?"

Les événements entraînent une surcharge minime par rapport à un appel de fonction normal.

L'utilisation de délégués peut créer des déchets implicites et donc cachés. Les déchets peuvent être une cause majeure de problèmes de performances, en particulier sur la XBox360.

Le code suivant génère environ 2 000 octets d'ordures par seconde (à 60 ips) sous la forme d'objets EntityVisitor:

    private delegate void SpacialItemVisitor(ISpacialItem item);

    protected override void Update(GameTime gameTime)
    {
        m_quadTree.Visit(ref explosionCircle, ApplyExplosionEffects);
    }

    private void ApplyExplosionEffects(ISpacialItem item)
    {
    }

Tant que vous évitez de générer des déchets, les délégués sont suffisamment rapides pour la plupart des tâches. En raison des dangers cachés, je préfère les éviter et utiliser plutôt les interfaces.

Pendant mon temps libre loin du vrai travail, j'ai aussi appris XNA.

IMHO (ou pas si humble si vous demandez à mes collègues) est que les frais généraux des poignées de l’événement seront submergés par d’autres éléments du jeu tels que le rendu. Compte tenu de la forte utilisation des événements dans la programmation .Net normale, le code sous-jacent est bien optimisé.

Pour être honnête, je pense que l’utilisation d’une méthode UpdateCameras pourrait être une optimisation prématurée. Le système d’événements a probablement d’autres utilisations que la caméra.

XNA encourage l'utilisation d'interfaces, d'événements et de délégués pour gérer quelque chose d'écrit avec. Jetez un coup d’œil aux classes liées à GameComponent qui vous permettent de le configurer.

La réponse est: "Autant que vous êtes à l'aise avec".

Pour élaborer un peu, par exemple, si vous prenez et héritez de la classe gamecomponent dans une classe cameracontroller et ajoutez-la à la collection Game.Component. Ensuite, vous pouvez créer vos classes de caméra et les ajouter à votre cameracontroller.

Cela permettra au cameracontroller d'être appelé régulièrement et de pouvoir sélectionner et activer la bonne caméra ou plusieurs caméras si c'est ce que vous recherchez.

Voici un exemple (tous ses tutoriels sont excellents): ReoCode

En passant, vous serez peut-être intéressé de savoir que Shawn Hargreaves , développeur original de Allegro , est l'un des principaux développeurs de l'équipe XNA: -)

Avant d'entrer dans l'impact d'un événement sur les performances, vous devez d'abord évaluer s'il est nécessaire ou non.

En supposant que vous essayez réellement de maintenir une caméra de poursuite à jour et que ce n’est pas un exemple, ce que vous recherchez n’est pas un événement (bien que les événements puissent faire tout aussi bien l'affaire), si vous suivez un avatar, la probabilité est il bougera la plupart du temps.

L’une des méthodes que j’ai trouvée extrêmement efficace consiste à utiliser des transformations hiérarchiques. Si vous l’implémentez efficacement, la caméra ne sera pas le seul objet à bénéficier d’un tel système. L’objectif serait de la garder dans l’espace de coordonnées du objet qu'il suit.

Cette approche n’est pas la meilleure si vous souhaitez appliquer une certaine élasticité à la vitesse et aux moyens utilisés par la caméra pour suivre l’objet. Pour cela, il est préférable d’utiliser un appel de mise à jour, une référence et des accélérations de base et physique de la résistance.

Les événements sont plus utiles pour des choses qui n'arrivent que de temps en temps ou qui affectent de nombreux aspects de l'application, comme un personnage mourant, de nombreux systèmes souhaiteraient probablement être conscients d'un tel événement, des statistiques de suppression, le contrôle L'intelligence artificielle, et ainsi de suite, dans ce cas, il est beaucoup moins efficace de garder une trace de tous les objets qu'il faudrait constamment vérifier si cela s'est produit. Il suffit de lancer un événement et de ne notifier tous les objets intéressés que lorsque cela se produit. / p>

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