Estoy empezando mi primer proyecto de juego 'adecuado', e inevitablemente he llegado a un bloque tratando de decidir cómo deben comunicarse los componentes del juego en XNA.
De los eventos de programación de GUI (Java) anteriores, los controladores y los oyentes parecían el camino a seguir. Por lo tanto, tendría algún tipo de bus de eventos que acepte registros de eventos y clases suscritas a esos eventos, con controladores para tratar con ellos. Por ejemplo (pseudocódigo):
class SpriteManager
Update(){
if(player.collidesWith(enemy)
// create new 'PlayerCollisionEvent'
}
class HUDManager
onPlayerCollisionEvent(){
// Update the HUD (reduce lives etc)
}
Sin embargo, no estoy seguro de la configuración del código (en C #) que se requeriría para lograr esto completamente. ¿Qué hace un seguimiento de los eventos (algún tipo de autobús?) Y cómo está estructurado?
También parece que se menciona mucho en Game Services, por lo que puede registrar un GameComponent en su clase principal de Game.cs, luego buscarlo en cualquier parte de su código que tenga una referencia al objeto principal 'Juego'. He intentado esto con mi objeto SpriteBatch y parece muy fácil ... sin embargo, no puedo ver que sea tan flexible como un modelo de evento.
Tomemos, por ejemplo, cuando un enemigo muere. Queremos actualizar la puntuación del juego. Al usar los servicios, puedo obtener una referencia a mi objeto StateManager creado en el Juego 1 y agregado como un servicio, luego establezco 'puntaje' al nuevo valor. Pensé que un evento 'onEnemyDeath', que puede ser manejado de manera diferente por una multitud de clases, pero iniciado por 1 línea de código en la sección relevante 'detección de muerte enemiga', sería mejor que lanzar individualmente cada GameComponent requerido y luego llamar a lo que sea Se requieren métodos.
¿O son estas estrategias inferiores a algo más?
Me doy cuenta de que esto es en parte mi pobre conocimiento de C # tanto como los paradigmas de comunicación del juego, pero realmente me gustaría entender bien esto.
Actualizar
Habiendo visto los Servicios es más detalle, estoy menos convencido: básicamente está pasando una variable global (por lo que entiendo).
Actualización 2
Después de echar un vistazo a este tutorial básico sobre el manejo de eventos y probar el código de muestra, parece que los eventos serían una elección lógica para lo que estoy discutiendo. Pero no puedo usarlo mucho en las muestras que he visto. ¿Hay alguna razón obvia por la que uno no debería?
fuente
Respuestas:
La razón por la que no encontrará mucho acerca de los buses de eventos en C # es porque no creo que nadie fuera de Java llame a tal cosa un 'bus', en mi experiencia. Los términos más comunes pueden ser cola de mensajes, administrador de eventos, señales / ranuras, publicación / suscripción, etc.
No necesitas ninguno de esos para hacer un juego que funcione, pero si ese es el tipo de sistema con el que te sientes cómodo, también te servirá bien aquí. Desafortunadamente, nadie puede decirle exactamente cómo hacer uno porque todos los usan de manera un poco diferente, incluso si los usan. (No lo hago, por ejemplo). Puede comenzar con un simple
System.Collections.Generic.List<Event>
para la cola, con sus diversos eventos como subclases de Evento y una lista de suscriptores para cada tipo de evento. Para cada evento en la cola, obtenga la lista de suscriptores, y para cada suscriptor, solicítelahandle(this_event)
. Luego quítelo de la cola. Repetir.Probablemente no sea tan flexible, pero es más fácil de depurar. Los eventos y mensajes son complicados porque desacoplan la función de llamada de la función llamada, lo que significa que las pilas de llamadas no son muy útiles al depurar, las acciones intermedias pueden hacer que algo se rompa, lo que normalmente funciona, las cosas pueden fallar en silencio cuando no se conectan correctamente , y así. El método explícito de "agarrar un componente y llamar a lo que necesita" funciona bien cuando se trata de detectar errores desde el principio y tener un código claro y explícito. Simplemente tiende a generar código estrechamente acoplado y muchas dependencias complejas.
C # es prácticamente un lenguaje idéntico a Java. Lo que haya hecho en Java se puede hacer en C #, solo que con una sintaxis diferente. Si tiene problemas para traducir un concepto, probablemente sea porque solo conoce un nombre específico de Java para él.
fuente
¿Has probado simplemente usando eventos estáticos simples? Por ejemplo, si desea que su clase de puntaje sepa cuándo murió un enemigo, haría algo como esto:
Score.cs
EnemySpaceship.cs
SpaceshipDeathEventArgs.cs
fuente
Si se siente incómodo con el enfoque basado en eventos, pruebe Artemis C #, es un marco de Entity System basado en http://t-machine.org/index.php/2007/09/03/entity-systems-are -the-future-of-mmog-development-part-1 /
Fuente: https://github.com/thelinuxlich/artemis_CSharp Ejemplo de juego: https://github.com/thelinuxlich/starwarrior_CSharp
fuente
intenta usar el agregador de eventos como este
fuente