Dovrei usare Eventi in un gioco XNA?


8

Ho creato una classe di pulsanti che disegna un pulsante sullo schermo. Quando faccio clic su di esso, voglio vedere qualcosa succedere. In WinForm, vorrei semplicemente usare l'evento OnClick del pulsante. Che mi dici di XNA?

Devo aggiungere un evento OnClick alla mia classe di pulsanti? È una buona pratica? Altrimenti, come gestisci gli eventi nel tuo ciclo di gioco?


Dovrai scrivere il tuo evento onClick. Qualcosa che prende l'attuale posizione del mouse e corrisponde a quella in cui si trova il tuo pulsante
Jeff

Risposte:


7

L'unico motivo per non utilizzarlo eventin un gioco è che la creazione di un delegato da allegare al gestore eventi crea un oggetto heap che può causare una garbage collection che può causare un singhiozzo di frame rate su Xbox 360 (e possibilmente WP7, non hanno testato esso).

In generale, questo non dovrebbe essere rilevante per un'interfaccia utente di gioco che hai impostato una volta e semplicemente lasciato correre.

Inoltre, chiamare un gestore di eventi è un po 'più piccolo, un po' più lento di alcuni altri metodi disponibili. E questo è anche assolutamente irrilevante per un'interfaccia utente. (Entra in gioco solo per lo scricchiolio dei numeri micro-ottimizzato).

Quindi, fintanto che non stai andando in giro ad assegnare gestori di eventi tutti volenti o nolenti, la scelta di usare un eventin un gioco non è diversa dalla scelta di usarne uno in un'applicazione normale.

Copiare il design di WinForms per l'interfaccia utente del tuo gioco va benissimo.

(Vale la pena sottolineare che un avvertimento degli eventi è che si tratta di riferimenti forti "nascosti" che possono involontariamente mantenere in vita gli oggetti se non si rimuove il gestore. Ciò è rilevante sia per i giochi che per le normali applicazioni)


4

È perfettamente accettabile utilizzare eventi per gestire cose come clic e altre interazioni con l'interfaccia dei pulsanti; è certamente un metodo superiore a quello che prevede la sottoclasse del Buttontipo per implementare comportamenti personalizzati.

Un'altra alternativa non comune è quella di collegare gli script ai pulsanti e ad altri elementi dell'interfaccia utente, ma questo è più coinvolto (a meno che non si disponga già di un solido sistema di scripting) e non necessariamente migliore.

Potresti anche voler esaminare il concetto di " GUI in modalità immediata ", che forniscono un altro modo di gestire l'input.


Mi sto solo chiedendo in che modo la tua risposta differisce dalla mia? c'è un metodo che differisce tra noi?
Ali1S232,

3

Ci sono tre approcci comuni che ho visto nei motori di gioco, non sono sicuro che XNA supporti tutti e tre ma eccoli qui:

  1. puoi ereditare una classe dalla tua classe button e sovrascrivere OnClickFunction nella tua classe CustomButton. Il vantaggio è che non è necessario verificare se il pulsante viene premuto per informarti ogni volta che si fa clic, ma potrebbe causare un uso eccessivo dell'ereditarietà.

  2. puoi definire alcune funzioni OnClick e passarle alla classe butten OnClickEvent (proprio come la normale gestione degli eventi c #). questo ha lo stesso vantaggio del precedente e non devi preoccuparti dell'abuso dell'ereditarietà.

  3. devi controllare nel tuo ciclo principale se si fa clic su questo pulsante o meno. in questo metodo non è davvero un evento. quindi lo svantaggio è che devi controllare te stesso ogni volta che devi fare qualcosa in base agli input dei pulsanti, ma ha un vantaggio che puoi controllare dove i pulsanti sono realmente controllati ed avere effetto.


2

Ho smesso di usare gli eventi .net e ho iniziato a memorizzare tutti i miei eventi e le modifiche nel buffer:

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

Professionisti:

  1. Per il supporto del multithreading l'unica cosa di cui hai bisogno è scambiare i buffer ed elaborare tutti gli eventi e le modifiche nel thread di rendering.
  2. Ogni modifica del gamestep verrà salvata, quindi qualsiasi logica di gioco può essere basata sulla combinazione di eventi. Puoi persino implementare l'inversione del tempo.
  3. Non è necessario creare campi evento per aumentare le dimensioni del singolo oggetto. La logica di gioco nella maggior parte dei casi richiede solo un singolo abbonato raro.
  4. Non c'è quasi nessuna allocazione di memoria aggiuntiva (esclusi i casi di boxe) (WP7, XBox e altri micro framework critici).
  5. Puoi avere diversi set di eventi che gestiscono un GameStateData predefinito su oggetto.

Contro:

  1. Maggiore spesa di memoria, sebbene siano necessari solo 3 buffer (gioco, scambio e rendering).
  2. Scrivere codice aggiuntivo all'inizio per implementare le funzionalità necessarie.

A proposito, a volte uso entrambi: modello di eventi e modello di buffer.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.