2008-09-15 15 views
11

No tengo juegos programados desde hace 10 años (mi última experiencia fue DJGPP + Allegro), pero pensé en echar un vistazo a XNA durante el fin de semana para ver cómo se perfilaba.Programadores de eventos y programación de juegos

Estoy bastante impresionado, sin embargo, como sigo armando un motor de juego, tengo una (probablemente) pregunta básica.

¿Cuánto debe confiar en los delegados y eventos de C# para conducir el juego? Como programador de aplicaciones, uso delegados y eventos en gran medida, pero no sé si hay una sobrecarga significativa para hacerlo.

En mi motor de juego, he diseñado una especie de "chase cam", que se puede unir a un objeto y luego recalcular su posición relativa al objeto. Cuando el objeto se mueve, hay dos formas de actualizar la cámara de persecución.

  • Tiene un método "UpdateCameras()" en el bucle principal del juego.
  • Usa un controlador de eventos y haz que la cámara de seguimiento se suscriba al objeto.OnMoved.

Estoy utilizando este último, porque me permite encadenar eventos juntos y automatizar muy bien grandes partes del motor. De repente, lo que sería enorme y complejo se dejó caer a un puñado de 3-5 manejadores de eventos de línea ... Es una belleza.

Sin embargo, si los controladores de eventos que disparan cada nanosegundo resultan ser una desaceleración importante, lo eliminaré y seguiré con el enfoque de ciclo.

Ideas?

Respuesta

10

Si pensara en un evento como una lista de suscriptores, en su código todo lo que está haciendo es registrar un suscriptor. Es probable que el número de instrucciones necesarias para lograr eso sea mínimo en el nivel de CLR.

Si quiere que su código sea genérico o dinámico, entonces necesita verificar si algo está suscrito antes de llamar a un evento. El mecanismo de evento/delegado de C# y .NET le proporciona esto a muy bajo costo (en términos de CPU).

Si realmente está preocupado por cada ciclo de reloj, nunca escribiría lógica de juego genérica/dinámica. Es una compensación entre el código mantenible/configurable y la velocidad absoluta.

Bien escrito, preferiría eventos/delegados hasta que pueda probar que es un problema.

La única forma en que realmente sabrás si es un problema para ti es perfilando tu código, ¡lo cual deberías hacer de todos modos para el desarrollo de cualquier juego!

1

XNA fomenta el uso de interfaces, eventos y delegados para conducir algo escrito con él. Eche un vistazo a las clases relacionadas con GameComponent que lo configuran para usted.

La respuesta es: "Tanto como te sientas cómodo".

Para elaborar un poco, si, por ejemplo, toma y hereda de la clase gamecomponent en una clase de controlador de cámara y agréguela a la colección Game.Component. Luego puedes crear tus clases de cámara y agregarlas a tu cámara controladora.

Hacer esto ocasionará que se llame al controlador de la cámara regularmente y pueda seleccionar y activar la cámara adecuada o varias cámaras si eso es lo que está buscando.

Aquí es un ejemplo de esto (Todas sus tutoriales son excelentes): ReoCode

1

En mi tiempo adicional fuera del trabajo real, yo he estado aprendiendo XNA también.

En mi humilde opinión (o no tan humilde si le preguntas a mis compañeros de trabajo) es que la sobrecarga de los controladores del evento será abrumado por otros elementos en el juego, como la prestación. Dado el uso intensivo de eventos en la programación .Net normal, yo sería el código subyacente que está bien optimizado.

Para ser sincero, creo que ir a un método UpdateCameras podría ser una optimización prematura. El sistema de eventos probablemente tenga más usos que no sean la cámara.

4

Es importante darse cuenta de que los eventos en C# no están en cola como eventos asincrónicos (como, por ejemplo, la cola de mensajes de Windows). Básicamente son una lista de indicadores de función. Así que plantear un evento no tiene peores consecuencias de rendimiento que iterar a través de una lista de indicadores de función y llamar a cada uno.

Al mismo tiempo, tenga en cuenta que, debido a esto, los eventos son sincrónicos. Si el oyente de su evento es lento, ralentizará la clase alzando los eventos.

1

Como acotación al margen, es posible que le interese saber que Shawn Hargreaves, desarrollador original de Allegro, es uno de los principales desarrolladores en el equipo de XNA :-)

+0

Lo noté. Es un pequeño mundo pequeño. – FlySwat

2

La cuestión principal parece ser: "¿Qué ¿La sobrecarga asociada con el uso de C# Delegates and Events? "

Los eventos tienen una sobrecarga significativa en comparación con una llamada de función normal.

El uso de Delegados puede crear basura implícita y, por lo tanto, oculta. La basura puede ser una causa importante de problemas de rendimiento, especialmente en el XBox360.

El código siguiente genera alrededor de 2000 bytes de basura por segundo (a 60 fps) en forma de objetos EntityVisitor:

private delegate void SpacialItemVisitor(ISpacialItem item); 

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

    private void ApplyExplosionEffects(ISpacialItem item) 
    { 
    } 

Siempre y cuando se evite la generación de basura, los delegados son lo suficientemente rápido para la mayoría de los propósitos. Debido a los peligros ocultos, prefiero evitarlos y usar interfaces en su lugar.

1

Antes de analizar cuál es el impacto de un evento en términos de rendimiento, primero debe evaluar si es necesario o no.

Suponiendo que realmente está tratando de mantener actualizada una chasecam y no es solo un ejemplo, lo que está buscando no es un evento (aunque los eventos también pueden hacer el truco), si está siguiendo una probabilidad de avatar ¿se moverá la mayor parte del tiempo?

Un enfoque que encontré extremadamente efectivo es usar transformaciones jerárquicas, si implementa esto de manera eficiente la cámara no será el único objeto que se beneficiará de dicho sistema, el objetivo sería mantener la cámara dentro del espacio de coordenadas de el objeto que está rastreando

Ese enfoque no es el mejor si desea aplicar cierta elasticidad a la velocidad y la forma en que la cámara rastrea el objeto, para eso, es mejor usar una llamada de actualización, una referencia y una aceleración básica y física de resistencia.

Los eventos son más útiles para cosas que solo suceden de vez en cuando o que afectan a muchos aspectos diferentes de la aplicación, como la muerte de un personaje, probablemente muchos sistemas diferentes deseen conocer un evento como este, matar estadísticas, controlar AI, y así sucesivamente, en tal caso, hacer un seguimiento de todos los objetos que tendrían que verificar constantemente si esto ha sucedido es mucho menos efectivo que lanzar un evento y que todos los objetos interesados ​​sean notificados solo cuando ocurra.

+1

Un nuevo nigromante ha llegado al barrio ... – Blau

Cuestiones relacionadas