Come collegare la macchina a stati finiti in un'architettura basata su componenti? [chiuso]


23

Le macchine a stati sembrano causare dipendenze dannose nelle architetture basate su componenti.

Come, in particolare, viene gestita la comunicazione tra una macchina a stati e i componenti che svolgono un comportamento legato allo stato?

Dove sono:

  • Sono nuovo alle architetture basate su componenti.
  • Sto realizzando un gioco di combattimento, anche se non penso che dovrebbe importare. Immagino che la mia macchina a stati venga utilizzata per alternare stati come "accovacciarsi", "precipitare", "bloccare", ecc.
  • Ho trovato questa tecnica di gestione dello stato come il sistema più naturale per un'architettura basata su componenti, ma è in conflitto con le tecniche di cui ho letto: Sistema di componenti di oggetti di gioco dinamici per personaggi a comportamento mutevole Suggerisce che tutti i componenti si attivano / disattivano controllando continuamente una condizione per l'attivazione.
  • Penso che azioni come "correre" o "camminare" abbiano senso come stati, il che è in disaccordo con la risposta accettata qui: /gamedev//a/7934
  • L'ho trovato utile, ma ambiguo: come implementare il comportamento in un'architettura di gioco basata su componenti? Suggerisce di avere un componente separato che non contiene altro che una macchina a stati. Ma ciò richiede una sorta di accoppiamento tra il componente della macchina a stati e quasi tutti gli altri componenti. Non capisco come debba essere gestito questo accoppiamento. Queste sono alcune ipotesi:

    A. I componenti dipendono dalla macchina a stati: i
    componenti ricevono riferimento ai componenti della macchina a stati getState(), che restituisce una costante di enumerazione. I componenti si aggiornano regolarmente e controllano se necessario.

    B. La macchina a stati dipende dai componenti:
    il componente a macchina a stati riceve riferimenti a tutti i componenti che sta monitorando. Interroga i loro getState()metodi per vedere dove si trovano.

    C. Qualche astrazione tra di loro
    Utilizzare un hub eventi? Pattern di comando?

    D. Separare gli oggetti di stato che fanno riferimento ai componenti
    State Pattern. Vengono creati oggetti di stato separati che attivano / disattivano un insieme di componenti. La macchina a stati commuta tra oggetti a stati.

  • Sto guardando i componenti come implementazioni di aspetti . Fanno tutto il necessario internamente per far accadere quell'aspetto. Sembra che i componenti dovrebbero funzionare da soli, senza fare affidamento su altri componenti. So che alcune dipendenze sono necessarie, ma le macchine a stati sembrano voler controllare tutti i miei componenti.

Risposte:


7

La panoramica è abbastanza leggera, ma dai un'occhiata a queste diapositive da una presentazione che ho fatto per New Game Conf l'anno scorso:

https://docs.google.com/presentation/d/110MxOqut_y7KOW1pNwIdcccisIA3ooJwVR-xm-ecuc4/view

(vedi le immagini pertinenti di seguito)

L'essenza della tecnica è quella di combinare il modello dell'elenco di azioni (spiegato - in qualche modo male - nelle diapositive) con macchine a stati comportamentali che agiscono su un'entità di gioco basata su componenti.

In sostanza è lo stesso che creare un sistema di composizione speciale solo per il comportamento dell'IA, orientato verso i tipi di integrazione inter-comportamentale di cui hai bisogno per sistemi di AI più semplici.

La mia parte preferita di quel particolare gioco era come poter creare nuovi tipi di nemici semplicemente selezionando da un elenco di comportamenti pre-scritti, inserendoli nell'elenco di azioni per l'oggetto di gioco (residente in un BrainComponent) nell'ordine desiderato priorità e tutto ha funzionato. Con un elenco di azioni che consente le azioni di blocco / non blocco, questo può fare alcune cose davvero interessanti nonostante quanto sia semplice da implementare.

Persino comportamenti come "stordimento" in cui solo uno StunBehaviorAction è stato inserito nella parte superiore dello stack dell'elenco azioni; se il comportamento di stordimento viene attivato (dopo aver osservato che il componente Orecchie dell'oggetto di gioco ha sentito un incredibile attacco di onde d'urto), ha impostato il suo stato interno su Stordito, ha detto al componente Animazione di riprodurre l'animazione di stordimento e ha impostato il suo stato di azione su Blocco, e il suo timer su un timeout di stordimento estratto dal componente EnemyParametersComponent dell'oggetto di gioco. Dal momento che era Blocking e in cima all'elenco delle azioni, nessuno degli altri BehaviorAction nell'elenco delle azioni avrebbe ricevuto il loro metodo di aggiornamento, quindi sarebbero stati sostanzialmente disattivati. Allo scadere del timeout, StunBehaviorAction ha ripristinato il suo stato su Inattivo e il suo stato di azione su Non blocco.

Gli altri comportamenti che abbiamo implementato sono stati quasi tutti implementati con una singola macchina a stati interna. Gli unici due che non avevano macchine a stati, infatti, erano PatrolPathBehaviorAction (spingeva una serie di PathAction nell'elenco di azioni se fosse inattivo, che a sua volta spingeva MoveAction) e GuardHomeBehaviorAction (sempre in fondo alla elenco di azioni e rimanderebbe sempre una PathAction alla posizione di partenza del nemico). Ogni altro comportamento era una macchina a stati.

Diapositiva 10 Diapositiva 25 Diapositiva 26


Qual è la differenza fondamentale tra "Comportamenti" e "Azioni"?
Cucciolo

1
@Pup: dal punto di vista del codice, come l'ho costruito, un comportamento è un'azione. Da un punto di vista concettuale, le azioni sono generalmente transitorie - esistono solo fino al "completo" - mentre i comportamenti sono per sempre e non vengono mai rimossi dall'elenco. Ho visto un altro team costruire un sistema simile ma con due elenchi, uno per Azioni e uno per Comportamenti, che funziona abbastanza bene. Mi piace avere la capacità di un'azione di bloccare determinati comportamenti, tuttavia, usando le maschere di bit e il raggruppamento (corsie, credo di averli chiamati nelle diapositive). Mi dispiace che la grafica della diapositiva centrale sia così male. :)
Sean Middleditch il

3

In un'azienda precedente per cui lavoravo, avevamo un sistema basato su componenti con intelligenza artificiale basata sullo stato. Avevamo un componente AI che controllava tutti i comportamenti per quell'oggetto / unità. Quando l'IA era attiva, come vagare, attaccare, ecc., Riceveva un aggiornamento ogni frame per fare qualsiasi logica necessaria. Quando l'intelligenza artificiale era inattiva o non si spostava il componente veniva disattivato e non aggiornato ogni frame. Il componente, sebbene disattivato, potrebbe ancora ricevere messaggi basati sugli eventi, quindi riceverebbe un messaggio per qualcosa come un giocatore che entra nel suo raggio di aggregazione e potrebbe rispondere a questo riattivando il componente AI in modo da poter fare aggiornamenti basati su frame.

Il componente AI ha dei sottocomponenti, che potrebbe creare e distruggere al volo, in base al tipo di azioni che stava eseguendo. Ad esempio, se stesse vagando, poteva creare un sottocomponente errante e aggiornare quel fotogramma mentre vagava, e quindi se aggro mentre vagava, chiudeva quel sottocomponente e apriva un sottocomponente di attacco. Il componente AI dovrebbe essere indipendente da tutti gli altri componenti su un oggetto. Ad esempio, avevamo un componente di input, che avrebbe semplicemente cercato valori di movimento su un'unità. La query che faceva era qualcosa a cui gli oggetti umani e di intelligenza artificiale avrebbero risposto. Ciò ha permesso al componente AI di impostare semplicemente i valori di movimento su se stesso durante cose come vagabondaggio, su cui il componente di input poteva captare, proprio come un componente controllabile dall'uomo avrebbe impostato valori su cui il componente di input poteva captare.


Quindi, i sottocomponenti AI stanno effettivamente facendo il lavoro? Esistevano come componenti di entità, allo stesso livello del componente AI?
Cucciolo

I sottocomponenti del nostro motore facevano parte della classe dei componenti di base. Quindi qualsiasi Component, da cui deriva BaseComponent, potrebbe avere un numero qualsiasi di SubComponents su di esso. Il Update()metodo in BaseComponentverificherebbe l'elenco dei sottocomponenti e li chiamerebbe Update(). Subcomponentserano del tutto opzionali quindi BaseComponentpotrebbe non averne. Inoltre, tutti i messaggi inviati a un componente venivano instradati anche ai sottocomponenti.
Nic Foster,

1

Non è chiaro cosa intendi per componenti poiché i tuoi termini sono molto vaghi senza esempi concreti. Spesso le entità di gioco sono costruite usando la composizione anziché l'ereditarietà. Quindi potresti trasformarli in qualcosa che può subire danni aggiungendo un componente di salute all'entità o potresti renderli animati aggiungendo un componente animato. Si potrebbe anche mettere l'IA in un tale componente. Ci sarà una logica decisionale nel tuo componente AI e se sei preoccupato di accoppiarlo a gran parte dell'altro codice nel sistema, potresti raccogliere le informazioni in una lavagna alla quale è consentito solo l'accesso alla logica AI. C'è anche il problema delle dipendenze dall'output del sistema AI. Fondamentalmente la tua IA sta controllando un'entità e quel controllo ha bisogno di un'interfaccia. Un concetto utile è quello di un controller o un gamepad. La tua IA può compilare una struttura simile a quella che un gamepad del giocatore avrebbe compilato (anche se potrebbe avere alcuni "pulsanti" extra per abilità specifiche). Ora questa struttura potrebbe quindi essere passata al componente animato che lo interpreterebbe e selezionerebbe le animazioni appropriate da riprodurre. Diversi sottocomponenti di intelligenza artificiale potrebbero persino scrivere in diversi campi della struttura o negli stessi campi con priorità diverse. Mirare e camminare per esempio. Diversi sottocomponenti di intelligenza artificiale potrebbero persino scrivere in diversi campi della struttura o negli stessi campi con priorità diverse. Mirare e camminare per esempio. Diversi sottocomponenti di intelligenza artificiale potrebbero persino scrivere in diversi campi della struttura o negli stessi campi con priorità diverse. Mirare e camminare per esempio.

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.