Registrar componentes de objetos de jogo em subsistemas de jogos? (Design de objeto de jogo baseado em componente)

11

Estou criando um sistema de objetos de jogo baseado em componentes . Algumas dicas:

  1. GameObjecté simplesmente uma lista de Components.
  2. Existem GameSubsystems. Por exemplo, renderização, física etc. Cada um GameSubsystemcontém ponteiros para alguns deles Components. GameSubsystemé uma abstração muito poderosa e flexível: representa qualquer fatia (ou aspecto) do mundo do jogo.

Há uma necessidade em um mecanismo de registrar Componentsem GameSubsystems(quando GameObjecté criado e composto). Existem 4 abordagens :


  • 1: Padrão de cadeia de responsabilidade . Tudo Componenté oferecido a todos GameSubsystem. GameSubsystemtoma uma decisão sobre qual Componentsregistro (e como organizá-los). Por exemplo, GameSubsystemRender pode registrar componentes renderizáveis.

pró. Componentsnão sabem nada sobre como eles são usados. Baixo acoplamento. A. Nós podemos adicionar novos GameSubsystem. Por exemplo, vamos adicionar o GameSubsystemTitles que registra todo o ComponentTitle e garante que cada título seja exclusivo e fornece interface para consultar objetos por título. Obviamente, ComponentTitle não deve ser reescrito ou herdado neste caso. B. Nós podemos reorganizar os existentes GameSubsystems. Por exemplo, GameSubsystemAudio, GameSubsystemRender, GameSubsystemParticleEmmiter podem ser mesclados em GameSubsystemSpatial (para colocar todo o áudio, emmiter, renderizar Componentsna mesma hierarquia e usar transformações relativas aos pais).

vigarista. Cheque de todos para todos. Muito ineficiente.

vigarista. Subsystemsconhecer Components.


  • 2: Cada um Subsystemprocura por Componentstipos específicos.

pró. Melhor desempenho do que em Approach 1.

vigarista. Subsystemsainda conhece Components.


  • 3: Componentregistra-se em GameSubsystem(s). Sabemos em tempo de compilação que existe um GameSubsystemRenderer, então vamos ComponentImageRender chamará algo como GameSubsystemRenderer :: register (ComponentRenderBase *).

pró. Atuação. Sem verificações desnecessárias como em Approach 1.

vigarista. Componentsestão mal associados GameSubsystems.


  • 4: Padrão do mediador . GameState(que contém GameSubsystems) pode implementar registerComponent (Component *).

pró. Componentse GameSubystemsnão sabem nada um do outro.

vigarista. Em C ++, pareceria um switch tipo-tipo feio e lento.


Perguntas: Qual abordagem é melhor e mais usada no design baseado em componentes? O que a prática diz? Alguma sugestão sobre a implementação de Approach 4?

Obrigado.

canto superior direito
fonte
Sinto cheiro de excesso de engenharia. Os componentes se registram no GameObject. Se GameSubsystem é o que eu acho que é, então é apenas uma lista de componentes que podem ser adicionados a um GameObject de uma só vez. Como você descreve, parece que existe algum tipo de "mágica" na forma como GameObjects e Componentes se reúnem (eles pesquisam um pelo outro? Por quê?) Também sinto que você está tentando usar componentes para basicamente tudo no seu mecanismo, o que eu também reconsideraria. Para o que vale a pena, eu consideraria apenas as opções 3 ou 4.
LearnCocos2D
@GamingHorror, registrando Componentsem GameObjectsestá fora do escopo da minha pergunta. Leia artigos sobre a abordagem baseada em componentes ou faça sua própria pergunta neste site, se estiver interessado nela. O que você pensa GameSubsystemé totalmente errado.
Topright
Sou inclinado a desenvolver componentes para a lógica do jogo, não os componentes do mecanismo, e sua descrição parecia apontar nessa direção. Entendo muito bem os sistemas componentes, acho que fui desviado do curso porque não estou familiarizado com a terminologia que você usou, especificamente o GameSubsystem. Pelo que li, parecia que você estava tentando construir tudo (por exemplo, o mecanismo inteiro) apenas a partir de componentes.
LearnCocos2D
Sim, "objetos de jogo baseados em componentes" e "programação orientada a componentes" são termos diferentes, pode ser confuso. Não ser tendencioso, ser melhor "bilased": scottbilas.com/files/2002/gdc_san_jose/game_objects_slides.ppt
topright

Respostas:

3

Número da porta 3 ... O componente se registra no GameSubsystem (s)

O componente está no lugar para manter o acoplamento abstraído do próprio GameObject. De alguma forma, em algum lugar algo de fato precisa interagir com os subsistemas e esse é o componente e seu objetivo.

O acoplamento não é realmente uma coisa ruim neste caso.

O desempenho é essencialmente necessário nesse caso, se você espera ter alguma complexidade em seu sistema, você simplesmente não pode permitir as abordagens de estilo de pesquisa das outras opções.

Finalmente, se um subsistema precisa ser reativo a outro (renderizador, física, áudio precisam fazer coisas quando algo acontece), os componentes podem facilitar isso entre si através do objeto de jogo e manter esse tipo específico de acoplamento entre sistemas gerenciado por meio do componentes.

Rick
fonte
1
Isso é bom. Mas como os componentes sabem sobre o GameSubsystems? Todos os subsistemas são singletons? Isso não é feio? ... Estou pensando em outra solução, como injeção de dependência ... mas quando e quem passa a instância do subsistema para cada componente?
24411 Dani
O @Dani Components não precisa acessar diretamente a instância do subsistema, apenas envia uma mensagem solicitando que o registro seja feito, não precisa saber o que é o subsistema (mas provavelmente o fará) E por que eles seriam singletons? Isso não é um requisito, mesmo que na maioria dos casos você precise apenas de uma única instância de subsistema para cada subsistema.
Pablo Ariel
@ Pablo - concordo.
Rick