Cambiamenti di stato in entità o componenti


9

Ho dei problemi a capire come gestire la gestione dello stato nelle mie entità.

Non ho problemi con la gestione dello stato di gioco, come pause e menu, dal momento che questi non sono gestiti come un sistema componente entità; solo con lo stato in entità / componenti.

Attingendo dagli Orchi deve morire come esempio, ho le mie entità MainCharacter e Trap che hanno solo i loro componenti come PositionComponent, RenderComponent, PhysicsComponent.

Ad ogni aggiornamento l'Entità chiamerà aggiornamento sui suoi componenti. Ho anche un EventManager generico con listener per diversi tipi di eventi.

Ora devo essere in grado di posizionare le trappole: prima selezionare la posizione trappola e trappola, quindi posizionare la trappola.

Quando si posiziona una trappola, questa dovrebbe apparire di fronte al MainCharacter, resa in modo diverso e seguendola. Una volta posizionato, dovrebbe semplicemente rispondere alle collisioni ed essere reso in modo normale.

Come viene generalmente gestito nei sistemi basati su componenti?

(Questo esempio è specifico ma può aiutare a capire il modo generale di trattare gli stati delle entità.)


1
È possibile aggiungere e rimuovere componenti di entità in base a eventi di input? Forse puoi cambiare i componenti della trap quando cambiano gli stati. Ad esempio, durante il posizionamento della trap avrà FollowComponent e RenderEffectComponnent. Quando viene posizionato, rimuovi entrambi i componenti e aggiungi CollisionComponent. (Modifica: espresso più chiaramente da Martin Sojka)
Asakeron,

Sì, posso, ogni input viene tradotto da un "HumanView" in eventi di gioco, che, la maggior parte, vengono prima elaborati dalla mia classe GameLogic, che verificherà ad esempio se MainCharacter ha abbastanza soldi per piazzare una trappola, come succede dopo che è quello che sto cercando di capire.
GriffinHeart,

Risposte:


6

Un'applicazione interessante di un sistema di componenti è che è possibile modificare i componenti di un'entità in fase di esecuzione se è stato progettato per essere in grado di gestirli. Lo stato di un'entità diventa quindi la somma di entrambi i componenti che le sono assegnati e quali valori detengono.

Per il tuo esempio, puoi prima creare la trappola con a BuildControllerComponent(governando la reazione ai controlli del giocatore in fase di costruzione), a PositionComponente a RenderComponent. L'ultimo ha un campo di dati che regola i pixel shader utilizzati e uno di questi conferisce alla trappola da costruire un aspetto "spettrale". Noterai che non sono stati ancora assegnati componenti di fisica.

Dopo aver posizionato la trappola, i componenti vengono scambiati. Non BuildControllerComponentè più necessario, quindi viene rimosso. Gli RenderComponentshader vengono sostituiti con la normale vista standard della trappola. Infine, PhysicsComponentoltre a tutto il necessario per far funzionare la trappola vengono aggiunti all'entità.

In un approccio basato sull'ereditarietà, questo equivale ad avere un costruttore per una ActiveTrapEntityclasse che accetta una BuildTimeTrapEntityclasse come argomenti, la seconda viene utilizzata per rendere la trap durante la sua costruzione, la prima viene utilizzata per la trap dopo che è stata posizionata .


Questo è intelligente.
Cypher,

1
Questa è una buona strategia per applicare lo stato di un'entità. Non affronta il problema di come tenere traccia dello stato di ciascuna entità. Come fai a sapere in quale stato si trova attualmente l'entità?
MichaelHouse

@MartinSojka Questo si avvicina a quello a cui stavo pensando dopo aver posto la domanda. Stavo pensando di aggiungere un BuildTrapProcess (qualcosa che viene aggiornato su GameLogic) che gestirà l'aspetto di runtime della modifica dei componenti per ottenere i cambiamenti di stato necessari per creare una trappola. Quando viene premuto il pulsante per creare una trappola, la logica di gioco crea il processo e lo avvia. qualche idea su questo approccio?
GriffinHeart,

@ Byte56: in generale, è possibile eseguire una query sui componenti associati e sui relativi valori. In pratica, spesso devi solo conoscere il sottoinsieme rilevante dell'intero stato, ad esempio "Ha questa entità BuildControllerComponent?" o "Qual è la posizione di questa entità come registrata nella sua PositionComponent, se ne ha?" - quelli che fai controllando l'elenco dei componenti per quelli a cui sei interessato e facoltativamente interrogando (alcuni) dei loro valori.
Martin Sojka,

1
@GriffinHeart: implementerei semplicemente tutto ciò che è necessario per "costruire" la trappola nel sistema associato alla gestione di BuildControllerComponents. Deve già elaborare le modifiche al punto di vista del personaggio del giocatore (o della telecamera) e gli eventi di pressione del tasto e del mouse.
Martin Sojka,

5

Non mi piace l'idea di entità che chiamano aggiornamenti sui loro componenti (i sistemi dovrebbero fare il lavoro), e questo porterà a problemi nel mantenere i componenti inconsapevoli l'uno dell'altro.

È possibile aggiungere un componente aggiuntivo chiamato "Stato". Vi si accederà dai sistemi di rendering e di collisione. Il componente state è solo un flag con più stati disponibili. Per la situazione che descrivi gli stati sarebbero Playe Build. Quando il sistema di rendering vede che lo stato è Builddisegna l'oggetto traslucido. Quando il sistema di collisione vede lo Buildstato, non elaborerà le collisioni con il giocatore.

Ma davvero, se non hai sistemi e fai affidamento su componenti per fare tutto il lavoro che incapperai in molti problemi. I componenti non dovrebbero conoscersi a vicenda e non dovrebbero eseguire l'elaborazione.


Quello che stai dicendo è in conflitto, prima dovrebbero essere ignari (cosa che sono d'accordo), quindi segui avendo un componente a cui accedono gli altri. Puoi chiarire? Sto mantenendo i componenti disaccoppiati dal sistema di eventi.
GriffinHeart,

Sto dicendo entrambi. Sto dicendo che dovrebbero essere inconsapevoli e cercare di personalizzare la mia risposta a come penso che tu stia gestendo i componenti. Quando dici "Entità chiamerà aggiornamento sui suoi componenti" mi fa credere che non hai entità di elaborazione dei sistemi. Ho rimosso il linguaggio confuso e ho appena fatto dire sistemi. Stavo dicendo componenti perché capivo che era così che stavi aggiornando.
MichaelHouse

Mi piace l'idea di un StateComponentche può essere consumato da più sistemi.
Cypher,

1
È educato fornire un ragionamento per i voti negativi. Grazie.
MichaelHouse

2
In una nota diversa, la tua obiezione all'approccio del richiedente si basa sul presupposto che tutta la progettazione basata su componenti deve aggiornare i componenti da sistemi separati (come una progettazione di sistema di entità). Questo è un modo per farlo, ma certamente non l'unico, e non c'è motivo di dissuadere un tale approccio per un gioco che non ha bisogno di cicli di aggiornamento dei componenti per l'ottimizzazione della cache.
Sean Middleditch,
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.