Devo escrever meu próprio mecanismo de física, devido à integração de redes?

11

Atualmente, estou desenvolvendo um shooter de zumbi de cima para baixo, em tempo real. Estou codificando isso em Java, usando o JBox2D como meu mecanismo de física. Eu tenho codificado a rede esta semana e agora estou pronto para a sincronização física.

Estou planejando usar o modelo preditivo de cliente / servidor autoritário, no qual o cliente pode se mudar, desde que o servidor aprove mais tarde. Isso envolve o cliente enviando pacotes contendo dados de movimento para o servidor, e o servidor calculando a latência e simulando novamente o mundo a partir de um estado mais antigo.

Meu problema é que meu atual mecanismo de física, o JBox2D (basicamente uma porta do Box2D), não suporta reverter o mundo e, aparentemente, não é tão fácil serializar os dados do mundo. Eu tenho duas soluções, eu poderia modificar / estender meu mecanismo de física atual ou escrever o meu.

Razões para escrever meu próprio mecanismo de física -

  • Eu posso remover recursos desnecessários. Em um jogo de cima para baixo, eu realmente só preciso de mecânica de colisão e forças de manuseio. Nenhuma gravidade está envolvida.
  • Eu posso entender melhor o código e [provavelmente] seria mais fácil implementar funções de reversão

Razões para estender / modificar o JBox2D

  • Escrever meu próprio mecanismo de física seria uma quantidade significativa de trabalho, o que poderia ser complicado
  • JBox2D tem uma comunidade amplamente solidária, que pode me ajudar com meu desenvolvedor
  • JBox2D, possui otimizações específicas, para coisas como detecção de colisão, que o tornam útil
  • Alguns trabalhos já foram feitos sobre isso, mas pouco código foi compartilhado

Então quais são suas opiniões. Este é o meu primeiro jogo, e eu não sou um desenvolvedor profissional de jogos. Se alguém pudesse fornecer alguns links para o trabalho já realizado na área (de preferência usando JBox2D / Box2D / Java).

liamzebedee
fonte
Observe também que, se você usar o JBox2D, precisará usá-lo em strictfpqualquer lugar, o que afetará seriamente o desempenho. Caso contrário, o servidor e o cliente podem não obter exatamente os mesmos resultados. Eu recomendaria o uso de ponto fixo.
sam hocevar 12/12

Respostas:

7

A detecção de colisão em 2D é tão simples que nem sei por que você se incomodaria em usar um mecanismo de física em primeiro lugar. E já que todas as forças de manuseio são diretas ou em uma curva (sem cair, alterar diagnósticos etc.). Fazer o seu próprio é simples. Colisão:

são responsáveis ​​pelas 3 colisões possíveis que podem ocorrer em 2 retângulos:

  1. Borda a borda: bem simples, você obtém o eixo de uma única borda e outra e decide se elas ocupam o mesmo espaço ou se estão próximas o suficiente.
  2. Borda para canto: este será o mais comum se você tiver formas rotativas. Felizmente, também é bastante simples de implementar.
  3. Canto a canto: isso acontece tão raramente que nem vale a pena implementá-lo. A razão para isso é que duas coisas teriam que se mover exatamente em direções opostas no mesmo eixo exato até o último decimal calculado dos motores. Agora, se tudo gira em 45 ou 90 graus, vale a pena incluir (ainda que provavelmente ainda não seja)

EDIT: Como comentado, estou muito menos familiarizado com esse assunto e não deve ser consultado sobre a colisão de balas / projéteis.

Quando trabalhei com balas no espaço 2D, usei uma espécie de remendo que funcionava tanto em linha reta como em curva, onde lançava o projétil usando o mecanismo de física (que não fiz do zero) e usava colisão padrão.

Leia sobre como criar isso do zero nos comentários.


EDIT: * Confie em mim, * independentemente de qual, você precisará de alguma forma de acerto de contas no mecanismo de jogos, por causa dos projéteis e quantos projéteis podem estar na tela a qualquer momento. Você ABSOLUTAMENTE não deseja atualizar todos os marcadores na tela por quadro, em um determinado local. Mas é uma ótima maneira de tornar o jogo lento demais: D! Você só deve atualizar estas coisas apenas:

  • Um projétil está sendo jogado
  • A direção em que está sendo jogada
  • Se é curvado ou não
    • E se sim, qual é a função da curva
  • Que projétil é (isso explica gráficos, efeitos, danos, tudo)

Agora atualize os dados no mecanismo de acordo com esses dados, em vez de no servidor para cada maldito projétil, e envie dados de pacotes para cada marcador. (Imagine fazer isso com apenas duas metralhadoras na tela! Jesus!)

Joshua Hedges
fonte
É claro que é relativamente fácil de implementar, mas também estou interessado na otimização da detecção de colisões, que não tenho idéia de como implementar.
Liamzebedee
O método que descrevi realmente não exigirá otimização se você o fizer conforme descrito. A única otimização que pode ser necessária é o tempo em que você realiza as verificações e a frequência com que as colisões são atualizadas. Por exemplo: REALMENTE precisam ser atualizados quando houver possibilidade de colisão.
Joshua Hedges
Para expandir sobre o que afirmei pela última vez. Você realmente só precisa verificar a colisão de edifícios, por exemplo, quando seu personagem está se movendo em primeiro lugar. Você só precisa verificar a colisão de unidades, mesmo quando há unidades à vista que não são do seu personagem. Você só precisa verificar a colisão de projéteis, quando eles existirem (naquele momento). Você pode pular qualquer forma de detecção de tipo de colisão (é de ponta a ponta? De ponta a ponta? Etc.) depois de saber que algo está tocando outra coisa ou próximo a ela. Caso contrário, pule-o em geral.
Joshua Hedges
Exceto quando estou processando colisões no lado do servidor, no qual preciso detectar colisões para vários jogadores etc.
liamzebedee
4
@ MadPumpkin: seu excesso de confiança reflete mal em sua resposta; você está falando sobre a detecção de colisões, mas não menciona a detecção de colisões por varredura, que está no cerne absoluto do manuseio adequado de balas em um atirador 2D. Além disso, mesmo com a varredura, a resolução é tão importante quanto a detecção, pois você precisa decidir qual colisão ocorreu primeiro, resolver possíveis conflitos e talvez iniciar a resolução inteira novamente no caso de entidades removidas. Certamente não é o assunto trivial que você parece sugerir.
sam hocevar 12/12