Estou desenvolvendo um jogo usando pesquisas para o método de entrada. No entanto, agora que estou aprofundando os menus do jogo e outros componentes da interface do usuário, estou descobrindo que provavelmente gostaria de ter uma entrada orientada a eventos. Talvez até tendo os dois, usando eventos direcionados para a interface do usuário e sondando a entrada "mundo". Estou curioso para saber qual é o melhor caminho a percorrer.
Estou definindo a pesquisa como: a cada ciclo de atualização, verifico quais teclas são pressionadas, onde está o mouse, os botões pressionados, depois os percorremos e executamos ações com base nas informações coletadas.
Estou definindo evento orientado como: eventos baseados em interrupção, quando um evento acontece e a interrupção é acionada e um bloco de código é executado com base no evento.
Você acha que é melhor seguir todos os eventos, todas as pesquisas ou é aceitável uma combinação de ambos? Se você tem prós e contras, liste-os. Obrigado.
EDITAR
O jogo é baseado em Java / OpenGL, por isso será lançado no Windows / Mac / Linux. A possibilidade de estender isso para dispositivos móveis é baixa. O jogo é estilo RTS, terceira pessoa 3D.
EDIT 2
Ainda não estou totalmente satisfeito com a maneira como implementei isso, mas o que estou buscando é capturar eventos na minha interface do usuário e se eles não forem tratados por nenhum dos meus componentes da interface do usuário, passo o evento para o diretório "Mundo" para picking / seleção. Algo como:
@Override
private boolean handleEvent(Event event) {
if(hud.handleEvent(event)) {
return true;
}
return WORLD.handleEvent(event);
}
Dessa forma, não recebo cliques vazando pela interface do usuário para selecionar objetos atrás dos botões e o que não.
Atualmente, meus controles de câmera ainda são baseados em pesquisas, e isso parece estar funcionando por enquanto, mas posso atualizá-los mais tarde.
Agradeço todas as respostas, desculpe, eu só poderia escolher uma!
Respostas:
Depende dos requisitos do seu jogo e hardware. A maioria dos jogos geralmente está interessada em alterações no estado de entrada, ou seja, o usuário pressiona a tecla de disparo e sua arma começa a disparar, o usuário libera a tecla de disparo e sua arma para de disparar, o usuário pressiona a tecla de movimento e começa a se mover, solta a tecla de movimento e para de se mover , etc., para que um sistema de entrada orientado a eventos faça mais sentido nesses casos, pois as informações já estão em um formato adequado. Além disso, na plataforma Windows, você já recebe eventos para alterações no estado do teclado e do mouse; portanto, geralmente é uma conversão 1: 1 de eventos de entrada de baixo nível para eventos de jogo de alto nível. Com a pesquisa, muitas vezes você terá que gerar esses eventos manualmente comparando o estado entre o quadro atual e o último. Basicamente, "quais botões foram pressionados agora?"
Dito isto, em certas plataformas, você fica preso com a entrada de sondagem em um nível baixo e não há como evitar a verificação de borda. No entanto, sempre obtive os melhores resultados usando eventos para toda a lógica de alto nível, pois é assim que esses sistemas tendem a operar.
fonte
GetAsyncKeyState
é uma maneira simples de usar a pesquisa no Win32.Não vejo razão para que você não possa fazer as duas coisas e obter o melhor dos dois mundos.
Eventos de entrada são gerados por polling (em algum nível, o driver faz uma sondagem no hardware para ver em que estado está) e, como o loop principal faz uma sondagem em todos os dispositivos de entrada, você pode facilmente implementar o seu. Algo simples como abaixo é o que eu usei no passado.
Eu sei que você definiu eventos como interrupções e o que eu coloquei aqui não é "verdadeiramente baseado em eventos", mas não vejo o que a descrição acima não fornece que interrupções causam - a maioria dos usuários não notará o único quadro perdido, a menos que seu jogo seja executado em uma taxa de quadros muito baixa.
fonte
Existem dois problemas diferentes aqui:
Como você lê a entrada do usuário no SO / hardware?
Como você processa a entrada do usuário no seu mecanismo?
Para a leitura, isso depende claramente da sua plataforma e do tipo de entrada que você deseja ler. Observe que é fácil converter uma coisa para outra na sua camada de entrada. (Ou seja, aponte e emita eventos para o mecanismo ou ouça eventos e emita estado para o mecanismo.)
Para o processamento, existem algumas opções diferentes:
Para controle de movimento do jogador (e esquemas semelhantes), a pesquisa pode ser mais simples, pois você precisa recalcular a velocidade de cada quadro. É muito provável que seu loop interno seja baseado em pesquisas:
ou seja, algo como
speed += 1 if button.down else -1; clamp(speed, 0, 42);
Para eventos discretos (míssil de fogo, jogo de pausa, teletransporte para o outro lado do planeta), o processamento de eventos é preferível; caso contrário, seu código será repleto de
maybeLaunchMissile(key_state);
chamadas, e isso é ... ruim, tudo bem. ;)Espero que ajude.
fonte