Estou começando no meu primeiro projeto de jogo 'adequado' e, inevitavelmente, atingi um quarteirão tentando decidir como os componentes do jogo no XNA devem se comunicar.
Em eventos de programação GUI (Java) anteriores, manipuladores e ouvintes pareciam o caminho a seguir. Então, eu teria algum tipo de barramento de evento que aceita registros e classes de eventos inscritos nesses eventos, com manipuladores para lidar com eles. Por exemplo (pseudocódigo):
class SpriteManager
Update(){
if(player.collidesWith(enemy)
// create new 'PlayerCollisionEvent'
}
class HUDManager
onPlayerCollisionEvent(){
// Update the HUD (reduce lives etc)
}
No entanto, não tenho certeza da configuração do código (em C #) necessária para fazer isso completamente. O que mantém o controle de eventos (algum tipo de ônibus?) E como está estruturado?
Também parece haver muita coisa mencionada no Game Services, na qual você pode registrar um GameComponent na classe Game.cs principal e buscá-lo em qualquer lugar do código que tenha uma referência ao objeto 'Game' principal. Eu tentei isso com meu objeto SpriteBatch e parece muito fácil .. no entanto, não vejo isso tão flexível quanto um modelo de evento.
Tomemos, por exemplo, quando um inimigo morre. Queremos atualizar a pontuação do jogo. Usando serviços, posso obter uma referência ao meu objeto StateManager criado no Game1 e adicionado como um serviço, depois definir 'score' para o novo valor. Eu pensaria que um evento 'onEnemyDeath', que pode ser tratado de maneira diferente por várias classes, mas iniciado por 1 linha de código na seção 'detecção de morte inimiga' relevante, seria melhor do que lançar individualmente cada GameComponent necessário e depois chamar o que quer métodos são necessários.
Ou essas estratégias são inferiores a outra coisa?
Sei que esse é parcialmente o meu pobre conhecimento em C #, tanto quanto os paradigmas de comunicação de jogos, mas eu realmente gostaria de acertar essa coisa fundamental.
Atualizar
Observar os Serviços é mais detalhes, estou menos convencido - basicamente está passando uma variável global (pelo que entendi).
Atualização 2
Tendo examinado este tutorial básico sobre manipulação de eventos e teste do código de amostra, parece que os eventos seriam uma escolha lógica para o que estou discutindo. Mas não posso usá-lo muito nas amostras que já vi. Existe alguma razão óbvia para que alguém não deva?
fonte
Respostas:
O motivo de você não encontrar muito sobre barramentos de eventos em C # é porque, na minha experiência, acho que ninguém fora do Java chama isso de 'barramento'. Termos mais comuns podem ser fila de mensagens, gerenciador de eventos, sinais / slots, publicação / assinatura, etc.
Você não precisa de nenhum deles para criar um jogo funcional, mas se esse é o tipo de sistema com o qual você se sente confortável, ele também será útil aqui. Infelizmente, ninguém pode lhe dizer exatamente como fazer um, porque todo mundo os interpreta de maneira um pouco diferente, se é que os usa mesmo. (Não, por exemplo.) Você pode começar com um simples
System.Collections.Generic.List<Event>
para a fila, com seus vários eventos sendo subclasses de Event e uma lista de assinantes para cada tipo de evento. Para cada evento na fila, obtenha a lista de assinantes e, para cada assinante, liguehandle(this_event)
para ele. Em seguida, remova-o da fila. Repetir.Provavelmente não é tão flexível, mas é mais fácil depurar. Eventos e mensagens são complicados porque separam a função de chamada da função chamada, o que significa que suas pilhas de chamadas não são muito úteis durante a depuração; ações intermediárias podem causar a quebra de algo que normalmente funciona; as coisas podem falhar silenciosamente quando não são conectadas corretamente. , e assim por diante. O método explícito de "pegar um componente e chamar o que você precisa" funciona bem quando se trata de detectar erros desde o início e ter um código claro e explícito. Isso tende a levar a códigos fortemente acoplados e muitas dependências complexas.
C # é praticamente uma linguagem idêntica ao Java. Tudo o que você fez em Java pode ser feito em C #, apenas com sintaxe diferente. Se você tiver problemas para traduzir um conceito, provavelmente é apenas porque você conhece apenas um nome específico para Java.
fonte
Você já tentou usar eventos estáticos simples? Por exemplo, se você quiser que sua classe de pontuação saiba quando um inimigo morreu, faça algo assim:
Score.cs
EnemySpaceship.cs
SpaceshipDeathEventArgs.cs
fonte
Se você se sentir desconfortável com a abordagem baseada em eventos, tente o Artemis C #, é uma estrutura do Sistema de Entidades baseada em http://t-machine.org/index.php/2007/09/03/entity-systems-are -o-futuro-do-mmog-desenvolvimento-parte-1 /
Fonte: https://github.com/thelinuxlich/artemis_CSharp Exemplo de jogo: https://github.com/thelinuxlich/starwarrior_CSharp
fonte
tente usar o agregador de eventos como este
fonte