Devo e come separare le preoccupazioni di input e oggetti di gioco?


20

In ogni gioco uno sviluppatore deve in qualche modo gestire l'input, che si tratti di semplici eventi da tastiera e mouse, eventi touch o qualcosa come input dell'accelerometro. Questo input direttamente di oggetti indirettamente effetti nel gioco. A volte lo stesso input può influenzare oggetti diversi. Ora ho pensato a come modellarlo. Per come la vedo io ci sono due approcci diversi.

  • Lascia che l'oggetto di gioco stesso lo gestisca, iscriviti agli eventi e chiama i suoi metodi. Ciò ha il vantaggio di permettere agli oggetti di gioco stessi di decidere quali input causano quale azione. Uno svantaggio sembra essere che il codice di input viene alterato con il codice dell'oggetto di gioco "core". Inoltre, gli oggetti di gioco non sono consapevoli dello stato del resto del gioco e talvolta potrebbero non agire su eventi di input. Questo non sembra giusto.

  • Chiedi a un controller di input generale di occuparsi di tutti gli input e prendere decisioni su chi deve gestire quale evento. Questo sembra separare meglio le preoccupazioni, ma accoppia strettamente la classe controller di input agli oggetti di gioco. In qualche modo ha bisogno di sapere chi vuole ricevere quale evento e in quale stato. Neanche questo sembra giusto.

Quali strategie stai usando per gestire questo?

Risposte:


7

Consiglio di separare gli eventi di input dagli oggetti di gioco in modo da poter cambiare / aggiornare rapidamente le metodologie di input senza dover modificare ed eseguire il debug di 10 classi di oggetti. Esempi di passaggio da controlli solo tastiera a mouse + tastiera o semplicemente riassegnazione di tasti.

Invece di accoppiare strettamente l'input ai singoli oggetti di gioco, chiama un solo metodo per segnale di input univoco sull'oggetto di gioco e lascia che decida il modo in cui eseguirlo.

Utilizzare un controller di input per tenere traccia dello stato di input:

Up press event   -> dir = up
Down press event -> dir = down

Ogni volta che cambia lo stato di input, valuta se gli oggetti di gioco sono pronti per essere modificati:

set dir  ->  if gamestate != paused && battlemode == false
             ->  character.changeDir(dir);

Implementa metodi generali sui tuoi oggetti di gioco, che possono essere chiamati dal controller di input o altri oggetti di gioco, se necessario:

changeDir (dir)
setSpeed (walk/run)

7

Raccomando l'approccio MVC. In MVC gli oggetti di gioco devono solo preoccuparsi di modellare il sistema di gioco e fornire un'interfaccia di alto livello come move_left. Quindi disporre di un oggetto controller che si preoccupi di mappare l'input alle chiamate del modello. Non solo consente un facile cambio di controlli, ma offre una buona interfaccia per AI ma è solo un altro controller.

Nella tua seconda opzione dividerei il controller di input in due parti, una che gestisce il tocco effettivo del dispositivo, la tastiera, l'accel, qualsiasi altra cosa tu possa lanciarvi, facendoli mappare in un insieme generico di input. Quindi avere una seconda parte che associa input generici a input specifici del gioco. Di 'che le tastiere freccia su su mappano su input1 quindi toccando la parte superiore di un touchscreen si mappano anche su input1 e ora scrivi un secondo pezzo che mappa input 1 per saltare. Ora è possibile mappare qualsiasi IO Device, nonché la riproduzione memorizzata o gli input AI su questo sistema di input generico e avere una piccola parte specifica del gioco che carica ciò che input1 significa per il modello.


5
Ci sono molte discussioni altrove su questo sito sul perché MVC non è generalmente un modello appropriato per i giochi; ciò che lo stonemetal descrive non è nemmeno MVC, è solo astrazione; e "Usa MVC" non è una risposta, poiché MVC è una descrizione di un'intera classe di architetture e non un modo particolare di separare le preoccupazioni (né l'unico modo per farlo).

2
MVC dovrebbe fornirgli A) un articolo di Wikipedia per leggere B) una serie di variazioni su come affrontare la soluzione che ha dimostrato di funzionare C) Cito il modo in cui lo installerei in cui il modello espone un'interfaccia di alto livello che il il controller associa input di basso livello (reali o sintetici) ad azioni di alto livello e manipola direttamente il modello anziché un sistema di eventi.
stonemetal

1

Vorrei suggerire di fare in modo che il tuo gioco (il Modello ) definisca un elenco di possibili eventi di input (implementati come enum o oggetti con un'interfaccia di base in comune). Cose come MovingRightStarted, MovingRightStopped, FiredWeapon1, Escape, ecc ...

Il gioco definisce una struttura di dati (ad esempio a queue) che il tuo codice di input (il Controller ) può riempire con eventi di input.

Quindi il tuo gioco può eseguire il polling della struttura dei dati per ottenere gli eventi di input.

In questo modo, è possibile collegare diversi tipi di controller per alimentare il modello:

  • Solo tastiera
  • Tastiera + mouse
  • Telecomando da gioco
  • Touch screen
  • Intelligenza artificiale

Li devi solo inviare eventi di input al modello.


Penso di aver capito cosa intendi, fatta eccezione per la scelta di un queuetipo di dati come archivio per memorizzarlo. Potresti spiegare perché?
Robert Massa,

Ben tra 2 polling di eventi di input dal modello, il controller potrebbe aver inviato diversi eventi di azione ed è importante mantenere l'ordine dell'input dell'utente. Ecco perché ho scelto una struttura di dati FIFO. In realtà potrebbe anche essere necessario specificare a che ora esatta è successo l'input.
Splo
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.