É possível implementar um modo multiplayer para um clássico do arcade?
Desenvolver jogos de acção multijogadores suaves foi sempre um pouco desconcertante para mim. Como devo dividir as responsabilidades cliente-servidor e compensar as latências de rede para que a acção do jogo pareça instantânea? Eu queria encontrar respostas para essas perguntas.
P>Peguemos o clássico arcade de 1979 Asteroids e modificamos um pouco a sua premissa, para que se torne um deathmatch. Ironicamente, vamos saltar os asteróides epónimos. No caso do nosso jogo, eles serão substituídos por outros jogadores.
Usaremos Java 8, LibGDX como um framework de jogo, Jackson para serialização de dados e implementações de Socket.IO para comunicação cliente-servidor.
Se você ainda não está familiarizado com a LibGDX, eu encorajo você a fazer seu simples tutorial antes de ler mais, e se isso o deixou interessado, definitivamente mergulhe no excelente desenvolvimento do Udacity com a LibGDX e como fazer um jogo de plataforma usando LibGDX.
Tudo o que vamos construir aqui está disponível como um código no repositório de referência. Por favor note que parte do código é omitido nesta série, então seria melhor se você o tivesse em algum lugar.
LONELY IN THE UNIVERSE
Comecemos com o desenvolvimento de um jogo offline e o aprimoramos com capacidades multiplayer mais tarde. Nesta parte em particular, vamos lidar com mover uma nave e atirar balas no vazio, e vamos adicionar outro mockup player no futuro.
Então, configure um novo projeto LibGDX com apenas o sub-projeto Desktop e vamos entrar nele.
Quando a LibGDX terminar de inicializar, você precisará alterar a compatibilidade do código fonte de 1.6 para 1.8 nos arquivos build.gradle tanto no desktop quanto nos sub-projetos centrais. Note que se você quiser suportar construções HTML baseadas em Android e GWT você terá que usar no máximo a versão 1.7. No entanto, para este tutorial, tudo o que nos interessa é a área de trabalho. Eu também acho lambdas e streams introduzidos na 1.8 muito úteis :).
Vá em frente e apague tudo dentro do core/src/com/asteroids/game e começaremos a desenvolver pacotes do zero. Nesta parte, todo o nosso desenvolvimento acontecerá dentro do sub-projeto core.
Vocês gostariam de ler mais com exemplos de código? Tente em nosso blog:
Developing Lag Compensated Multiplayer Game - parte 1 - offline
A próxima parte que você vai precisar é configurar o servidor.
Sair da arquitetura cliente-servidor nós vamos desenvolver o servidor primeiro, já que o cliente tem que se conectar a algo. Em poucas palavras, o servidor irá rodar em ciclos: junte a entrada de Controles dos Jogadores, rode através de cálculos de lógica do jogo e finalmente envie de volta o estado atualizado do jogo para os clientes.
P>Pontos-chave do Several podem ser extraídos desta visão geral. Os clientes só enviarão a entrada de Controles e não o estado do jogo. Isso elimina a necessidade de validação do estado do cliente no lado do servidor (o cliente só pode dizer "minha tecla forward é pressionada", o que é sempre uma possibilidade válida, ao invés de "Estou totalmente em [20x,30y]" mesmo que tenha sido [20x,5y] no último frame). Isto, por sua vez, implica naturalmente que o servidor tem de correr a lógica do jogo para se tornar uma única fonte de verdade.
A fim de tornar possível que todos os clientes e um servidor tenham de comunicar usando um formato comum e manter um rápido canal de troca de mensagens de duas vias. Eles também precisam ter alguma forma de identificar objetos de jogo através da barreira da rede, então quando o servidor diz "este Bulletcollided with this Player" o cliente sabe qual é este Bullet e este Player. Sabendo disso, estamos prontos para implementar nossa lógica relacionada ao servidor.
INFRASTRUCTURAL CHORES
Lembre que a infraestrutura já está cuidada no repositório suplementar para esta série de artigos na parte 2: o servidor, então se você estiver codificando junto você pode simplesmente deletar tudo no código fonte do módulo e ter uma infraestrutura pronta.
P>Pára aqui? És um rapazinho teimoso, não és? Ok, primeiro vamos criar um módulo servidor novinho em folha, junto com outros módulos de nível superior (core, desktop, etc.). Ele será um pouco semelhante a um módulo desktop no sentido de que é executável, então podemos apenas pegar o build.gradle do desktop e ajustar os nomes de acordo com o servidor. Então criaremos o src/com/asteroids/game/servidor/namespace necessário dentro. Então precisaremos voltar à raiz do projeto Asteroids onde incluiremos o módulo server em settings.gradle, adicionaremos diretórios apropriados em .gitignore, e para um passo final mundano, adicionaremos tarefas para uma nova declaração de projeto:
[novamente, exemplos de código exibidos melhor no nosso blog:]
http://www.schibsted.pl/blog/back-end/developing-lag-compensated-multiplayer-game-pt-2/