Devo usar eventos em um jogo XNA?

8

Eu criei uma classe de botão que desenha um botão na tela. Quando clico nele, quero ver algo acontecendo. No WinForm, eu simplesmente usaria o evento OnClick do botão. E o XNA?

Devo adicionar um evento OnClick à minha classe de botão? Essa é uma boa prática? Caso contrário, como você lida com eventos no seu loop do jogo?

Martin
fonte
Você terá que escrever seu próprio evento onClick. Algo que assume a posição atual do mouse e a coincide com a posição de onde está o botão
Jeff

Respostas:

7

O único motivo contra o uso eventem um jogo é que a criação de um representante para anexar ao manipulador de eventos cria um objeto de heap que pode causar uma coleta de lixo que pode causar um soluço na taxa de quadros no Xbox 360 (e possivelmente o WP7, não testou isto).

Em geral, isso não deve ser relevante para uma interface do jogo que você configura uma vez e simplesmente deixa executar.

Além disso, chamar um manipulador de eventos é um pouquinho, muito, muito mais lento, alguns outros métodos disponíveis. E isso também é absolutamente irrelevante para uma interface do usuário. (Ele só entra em jogo para trituração de números micro-otimizada).

Portanto, contanto que você não esteja atribuindo manipuladores de eventos a todos os modos, a escolha de usar um eventem um jogo não é diferente da escolha de usar um em um aplicativo comum.

Copiar o design do WinForms para a interface do jogo é perfeitamente adequado.

(Vale ressaltar que uma ressalva dos eventos é que eles são referências fortes "ocultas" que podem manter objetos vivos involuntariamente se você não remover o manipulador. Isso é relevante para jogos e aplicativos regulares.

Andrew Russell
fonte
4

É perfeitamente aceitável usar eventos para lidar com coisas como cliques e outras interações com a interface do botão; certamente é um método superior ao que envolve subclassificar o Buttontipo para implementar um comportamento personalizado.

Outra alternativa incomum é anexar scripts a botões e outros elementos da interface do usuário, mas isso é mais envolvido (a menos que você já tenha um sistema de script robusto em vigor) e não é necessariamente melhor.

Você também pode querer examinar o conceito de " GUIs de modo imediato ", que fornecem outra maneira de lidar com as entradas.


fonte
Só estou me perguntando como é a sua resposta diferente da minha. existe algum método que difere entre nós?
Ali1S232
3

Existem três abordagens comuns que vi nos mecanismos de jogos, não tenho certeza sobre o XNA suportar os três, mas aqui estão elas:

  1. você pode herdar uma classe da sua classe de botão e substituir OnClickFunction na sua classe CustomButton. O benefício é que você não precisa verificar se o botão é pressionado; ele é informado sempre que é clicado, mas pode causar o uso excessivo de herança.

  2. você pode definir alguma função OnClick e passá-la à classe OnClickEvent butten (assim como a manipulação de eventos c # normal). isso tem o mesmo benefício que o anterior e você não precisa se preocupar com o uso excessivo de herança.

  3. você deve verificar no loop principal se esse botão é clicado ou não. Nesse método, não é realmente um evento. portanto, a desvantagem é que você deve verificar a si mesmo sempre que precisar fazer algo com base nas entradas dos botões, mas há uma vantagem de poder controlar onde os botões realmente são verificados e entrar em vigor.

Ali1S232
fonte
2

Parei de usar eventos .net e comecei a armazenar todos os meus eventos e alterações no buffer:

public sealed class GameStateData
{
    public bool IsEmpty = true;
    public List<EventData> EventDatas = new List<EventData>();
    public List<ChangeData> ChangeDatas = new List<ChangeData>();
    ...//your additional data

    public void Reset()
    {
        IsEmpty = true;
        ManifoldDatas.Count = 0;
        ChangeDatas.Count = 0;
    }
}

public struct ChangeData
{
    public Node Sender;
    public short PropertyIndex; // predefined property index (f.e. (short)MyIndexEnum.Life)
    public object OldValue;
    public object NewValue;
    public object AdditionalData;
}

Prós:

  1. Para suporte a multithreading, a única coisa que você precisa é trocar buffers e processar todos os eventos e alterações no thread de renderização.
  2. Todas as alterações de escala de jogo serão salvas, portanto, qualquer lógica de jogo pode ser baseada na combinação de eventos. Você pode até implementar a reversão do tempo.
  3. Você não precisa criar campos de eventos aumentando o tamanho de um único objeto. Na maioria dos casos, a lógica do jogo requer apenas um assinante raro.
  4. Quase não há alocação de memória adicional (excluindo casos de boxe) (WP7, XBox e outras micro estruturas críticas).
  5. Você pode ter conjuntos de eventos diferentes manipulando um GameStateData predefinido como objeto.

Contras:

  1. Mais gasto de memória, embora você precise de apenas 3 buffers (jogo, troca e renderização).
  2. Escrever código adicional no início para implementar a funcionalidade necessária.

BTW, às vezes, eu uso ambos: modelo de evento e modelo de buffer.

Romanenkov Andrey
fonte