Sto lavorando a un semplice puzzle game basato su blocchi.
Il gioco consiste praticamente nello spostamento di blocchi nell'area di gioco, quindi è una banale simulazione fisica. La mia implementazione, tuttavia, è secondo me tutt'altro che ideale e mi chiedo se puoi darmi qualche suggerimento su come farlo meglio.
Ho diviso il codice in due aree: logica di gioco e interfaccia utente, come ho fatto con molti giochi puzzle:
- La logica del gioco è responsabile delle regole generali del gioco (ad es. Il sistema formale di regole negli scacchi)
- L'interfaccia utente visualizza l'area di gioco e i pezzi (ad es. Scacchiera e pezzi) ed è responsabile delle animazioni (ad es. Movimento animato dei pezzi degli scacchi)
La logica di gioco rappresenta lo stato del gioco come una griglia logica, in cui ogni unità è la larghezza / altezza di una cella sulla griglia. Quindi, per una griglia di larghezza 6, puoi spostare un blocco di larghezza 2 quattro volte fino a quando non si scontra con il bordo.
L'interfaccia utente prende questa griglia e la disegna convertendo le dimensioni logiche in dimensioni dei pixel (ovvero, la moltiplica per una costante). Tuttavia, poiché il gioco non ha praticamente alcuna logica di gioco, il mio livello di logica di gioco [1] non ha molto da fare se non il rilevamento delle collisioni. Ecco come funziona:
- Il giocatore inizia a trascinare un pezzo
- L'interfaccia utente richiede la logica di gioco per l'area di movimento legale di quel pezzo e consente al giocatore di trascinarlo all'interno di quell'area
- Il giocatore lascia andare un pezzo
- L'interfaccia utente aggancia il pezzo alla griglia (in modo che sia in una posizione logica valida)
- L'interfaccia utente dice alla logica di gioco la nuova posizione logica (tramite metodi mutatori, che preferirei evitare)
Non ne sono abbastanza soddisfatto:
- Sto scrivendo unit test per il mio livello logico di gioco, ma non per l'interfaccia utente, e ho scoperto che tutto il codice complicato si trova nell'interfaccia utente: impedire al pezzo di scontrarsi con altri o il confine e farlo scattare sulla griglia.
- Non mi piace il fatto che l'interfaccia utente descriva la logica del gioco sul nuovo stato, preferirei che chiamasse un
movePieceLeft()
metodo o qualcosa del genere, come nei miei altri giochi, ma non sono andato lontano con questo approccio, perché la logica del gioco non sa nulla del trascinamento e dello snap possibile nell'interfaccia utente.
Penso che la cosa migliore da fare sarebbe liberarmi del mio livello logico di gioco e implementare invece un livello fisico. Ho alcune domande al riguardo:
- È comune un tale livello di fisica o è più tipico che il livello di logica di gioco lo faccia?
- Lo snap alla griglia e il trascinamento del pezzo di codice appartengono all'interfaccia utente o al livello fisico?
- Un tale livello fisico funzionerebbe in genere con dimensioni di pixel o con una sorta di unità logica, come il mio livello di logica di gioco?
- Ho visto una volta il rilevamento delle collisioni basato sugli eventi nella base di codice di un gioco, ovvero il giocatore avrebbe semplicemente trascinato il pezzo, l'interfaccia utente l'avrebbe reso obbediente e l'avrebbe notificato al sistema fisico e il sistema fisico avrebbe chiamato un metodo onCollision () sul pezzo una volta rilevata una collisione. Cosa è più comune? Questo approccio o chiedere prima l'area di movimento legale?
[1] layer probabilmente non è la parola giusta per quello che intendo, ma il sottosistema sembra esagerato e la classe è sbagliata, perché ogni layer può essere composto da più classi.