2010-04-11 8 views
7

Recentemente ho riscontrato alcuni problemi con il semplice passaggio di riferimenti a oggetti/nemici in un gioco che sto facendo e mi chiedo se sto usando l'approccio sbagliato.Quando scrivi un gioco, dovresti creare oggetti/nemici/ecc. avere numeri ID univoci?

Il problema principale che ho è lo smaltimento di nemici e oggetti, quando altri nemici o giocatori possono ancora avere collegamenti a loro.

Ad esempio, se si dispone di un coniglio e un lupo, il lupo potrebbe aver scelto il coniglio come bersaglio. Quello che sto facendo è che il lupo ha un GameObject Target = null; e quando decide che è affamato, il bersaglio diventa il coniglio. Se poi il Coniglio muore, come un altro lupo che lo uccide, non può essere rimosso dal gioco correttamente perché questo lupo ha ancora un riferimento ad esso.

Inoltre, se si utilizza un approccio disaccoppiato, il coniglio potrebbe colpire da un fulmine, riducendo la sua salute a sotto zero. Quando si aggiorna da solo, si rende conto che è morto e viene rimosso dal gioco ... ma non c'è modo di aggiornare tutto ciò che è interessato a esso.

Se si assegnava a ciascun nemico un ID univoco, è possibile utilizzare semplicemente i riferimenti e utilizzare una classe di ricerca centrale che la gestisse. Se il mostro fosse morto, la classe di ricerca avrebbe potuto rimuoverlo dal proprio indice, e successivamente qualsiasi tentativo di accedervi sarebbe stato informato che era morto, e quindi avrebbero potuto agire di conseguenza.

Qualche idea su questo?

+0

Perché non hai qualche evento "AnimalDied" o "HealthChanged" a cui un animale da caccia potrebbe iscriversi? Quando questi eventi sparano, il cacciatore potrebbe decidere autonomamente se interrompere la caccia a quella preda e annullare la sottoscrizione a quegli eventi. Una iena probabilmente vorrebbe ancora cacciare un coniglio morto, ma un lupo potrebbe non essere interessato nemmeno a un coniglio debole, figuriamoci a un morto. – slugster

risposta

2

L'approccio è ragionevole, perché no? Registrare tutti i tuoi oggetti in una hashmap non dovrebbe essere troppo costoso. Potresti quindi avere una sorta di bus eventi in cui gli oggetti potrebbero registrarsi per eventi diversi.

A parte questo, mi viene in mente un altro approccio. Potresti fare in modo che il coniglio esponga direttamente l'evento e faccia registrare il lupo su di esso.

Il secondo approccio è allettante per la sua semplicità, tuttavia sarà in grado di accoppiare gli editori dell'evento agli abbonati. Il primo approccio è tecnicamente più complesso ma ha il vantaggio di consentire anche altri tipi di ricerche.

+0

Intendi "accattivante", non "spaventoso"? –

+0

Sì, mi spiace solo un errore (rispondere ai messaggi dal mio iPhone è un dolore). –

7

Un possibile approccio consiste nel disporre di oggetti registrare un interesse con l'oggetto che sta monitorando. Quindi l'oggetto tracciato può informare dinamicamente i tracker delle modifiche di stato. per esempio. il Lupo si registra con il Coniglio (che ha una lista di parti interessate), e quelle parti vengono informate dal Coniglio ogni volta che c'è un cambiamento di stato.

Questo approccio indica che ciascun oggetto conosce i propri client e tale stato è direttamente collegato a quell'oggetto (e non in alcune classi di manager di terze parti).

Questo è essenzialmente il Observer pattern.

+0

Mi piace questo. Ha senso avere un valore nominale per me da scrivere per ogni evenienza. – Kawa

+0

Ho pensato molto a questo, e uno dei problemi è quando un lupo vuole esaminare un coniglio per vedere che tipo di possibilità avrebbe avuto di mangiarlo. In termini di programmazione, ciò significa ottenere l'oggetto coniglio e lanciarlo su un Mostro ed esaminarne le proprietà di salute e forza. Se il codice viene modificato in modo che non si occupi in termini di oggetti, come si verificherà questo tipo di interazione? – NibblyPig

+0

Forse è un semplice caso di cambiare il mio codice in modo che ogni _storage_ di mostri sia fatto da ID, ma qualsiasi cosa temporanea come esaminare i valori in essa può essere fatta con oggetti senza alcun problema. – NibblyPig

1

I riferimenti funzionano solo mentre il design rimane monolitico.

In primo luogo, il passaggio di riferimenti ad altri moduli (in particolare, script) comporta problemi di sicurezza e tecnici.

In secondo luogo, se si desidera estendere l'oggetto esistente implementando alcuni comportamenti e proprietà correlate in un nuovo modulo, non sarà disponibile un unico riferimento per tutte le occasioni.

2

In pratica non trovo quasi mai situazioni in cui sia necessario tenere un riferimento o un puntatore agli oggetti di gioco da altri oggetti di gioco.Ce ne sono alcuni, ad esempio l'esempio di targeting che date, e in quelle situazioni è dove i numeri ID univoci funzionano alla grande.

Suppongo che sia possibile utilizzare il modello di osservatore per tali elementi per garantire che i riferimenti vengano cancellati quando necessario, ma penso che inizierà a diventare disordinato se si necessita di più di 1 riferimento per oggetto, ad esempio. Potresti avere un oggetto di gioco di destinazione, potresti avere oggetti di gioco nel tuo gruppo corrente, potresti seguire un oggetto di gioco, parlare con uno, combattere uno, ecc. Questo probabilmente significa che il tuo oggetto di osservazione deve avere una funzione di pulizia monolitica che controlli tutto l'oggetto in uscita fa riferimento e li ripristina.

Personalmente ritengo sia più semplice utilizzare un ID e convalidare la continuità dell'esistenza dell'oggetto nel punto di utilizzo, anche se il prezzo è un po 'di codice boilerplate per farlo e il costo delle prestazioni della ricerca ogni volta.

+0

+1 per l'opzione leggera. I primi giochi su cui ho lavorato su tutti gli ID oggetto utilizzati per il riferimento agli oggetti erano semplici e robusti. L'osservatore e la registrazione degli eventi potrebbero funzionare bene, ma sono sostanzialmente più pesanti, molto più difficili da rintracciare nel debugger e generalmente più soggetti a errori. Semplice = buono, specialmente nei giochi. –

Problemi correlati