¿Debo usar Eventos en un juego XNA?

8

Creé una clase de botón que dibuja un botón en la pantalla. Cuando hago clic en él, quiero ver que algo sucede. En WinForm, simplemente usaría el evento OnClick del botón. ¿Qué hay de XNA?

¿Debo agregar un evento OnClick a mi clase de botón? ¿Es una buena práctica? De lo contrario, ¿cómo manejas los eventos en tu ciclo de juego?

Martín
fuente
Tendrás que escribir tu propio evento onClick. Algo que toma la posición actual del mouse y lo compara con el lugar donde está el botón
Jeff

Respuestas:

7

La única razón contra el uso eventen un juego es que la creación de un delegado para adjuntar al controlador de eventos crea un objeto de montón que puede causar una recolección de basura que puede causar un hipo de velocidad de fotogramas en Xbox 360 (y posiblemente WP7, no se ha probado eso).

En general, esto no debería ser relevante para una interfaz de usuario del juego que configuras una vez y simplemente dejas ejecutar.

Además, llamar a un controlador de eventos es un poco , muy pequeño, un poco más lento que otros métodos disponibles. Y esto también es absolutamente irrelevante para una interfaz de usuario. (Solo entra en juego para el procesamiento de números micro optimizado).

Por lo tanto, siempre y cuando no esté dando vueltas a la asignación de controladores de eventos de forma involuntaria, la elección de usar un eventen un juego no es diferente a la elección de usar uno en una aplicación normal.

Copiar el diseño de WinForms para la interfaz de usuario de tu juego está perfectamente bien.

(Vale la pena señalar que una advertencia de los eventos es que son referencias fuertes "ocultas" que pueden mantener vivos los objetos sin querer si no quitas el controlador. Esto es relevante tanto para juegos como para aplicaciones regulares)

Andrew Russell
fuente
4

Es perfectamente aceptable usar eventos para manejar cosas como clics y otras interacciones con la interfaz de su botón; Sin duda, es un método superior al que implica subclasificar el Buttontipo para implementar un comportamiento personalizado.

Otra alternativa poco común es adjuntar secuencias de comandos a botones y otros elementos de la interfaz de usuario, pero esto es más complicado (a menos que ya tenga un sistema de secuencias de comandos robusto) y de todos modos no es necesariamente mejor.

También es posible que desee analizar el concepto de " GUI de modo inmediato" , que proporcionan otra forma de manejar la entrada.


fuente
Me pregunto cómo es su respuesta diferente de la mía. ¿Hay algún método que difiera entre nosotros?
Ali1S232
3

Hay tres enfoques comunes que vi en los motores de juego, no estoy seguro de que XNA admita los tres, pero aquí están:

  1. puede heredar una clase de su clase de botón y anular OnClickFunction en su clase CustomButton. El beneficio es que no tiene que verificar si se presiona el botón, le informa cada vez que se hace clic, pero puede causar un uso excesivo de la herencia.

  2. puede definir alguna función OnClick y pasarla a la clase de butten OnClickEvent (al igual que el manejo normal de eventos de C #). Esto tiene el mismo beneficio que el anterior y no necesita preocuparse por el uso excesivo de la herencia.

  3. debe verificar en su bucle principal si se hace clic en este botón o no. en este método no es realmente un evento. por lo tanto, la desventaja es que debe verificarse a sí mismo cada vez que tiene que hacer algo en función de las entradas de los botones, pero tiene la ventaja de que puede controlar dónde se verifican realmente los botones y surten efecto.

Ali1S232
fuente
2

Dejé de usar eventos .net y comencé a almacenar todos mis eventos y cambios en el búfer:

public sealed class GameStateData
{
    public bool IsEmpty = true;
    public List<EventData> EventDatas = new List<EventData>();
    public List<ChangeData> ChangeDatas = new List<ChangeData>();
    ...//your additional data

    public void Reset()
    {
        IsEmpty = true;
        ManifoldDatas.Count = 0;
        ChangeDatas.Count = 0;
    }
}

public struct ChangeData
{
    public Node Sender;
    public short PropertyIndex; // predefined property index (f.e. (short)MyIndexEnum.Life)
    public object OldValue;
    public object NewValue;
    public object AdditionalData;
}

Pros:

  1. Para el soporte de subprocesos múltiples, lo único que necesita es intercambiar buffers y procesar todos los eventos y cambios en el hilo de renderizado.
  2. Cada cambio de gametep se guardará, por lo que cualquier lógica del juego puede basarse en una combinación de eventos. Incluso puede implementar la inversión de tiempo.
  3. No es necesario crear campos de eventos que aumenten el tamaño de un solo objeto. La lógica del juego en la mayoría de los casos requiere solo un suscriptor raro.
  4. Casi no hay asignación de memoria adicional (excluyendo los casos de boxeo) (WP7, XBox y otros micro framework críticos).
  5. Puede tener diferentes conjuntos de eventos manejando un GameStateData predefinido para objetar.

Contras:

  1. Más gasto de memoria, aunque solo necesita 3 buffers (juego, intercambio y renderizado).
  2. Escribir código adicional al inicio para implementar la funcionalidad necesaria.

Por cierto, a veces uso ambos: modelo de eventos y modelo de búfer.

Romanenkov Andrey
fuente