TUTORIAL 19 - CRIANDO JOGOS MULTIPLAYER COM O 3D GAME BUILDER


        Uma das novidades do 3D Game Builder 1.6 é o suporte a criação de jogos multiplayer em rede. Este tutorial ira mostrar como utilizar este recurso na criação de jogos multiplayer.

        Primeiramente aviso que este é um tópico avançado, antes de tentar criar um jogo multiplayer é necessário ter pelo menos o básico de conhecimento sobre redes de computadores, arquiteturas cliente/servidor, tcp/ip, protocolos de comunicação entre computadores, etc.

        Para a criação de jogos multiplayer o 3D Game Builder oferece 2 componentes que pode ser adicionados ao mapa do jogo, TCP Server e TCP Client, ambos disponíveis na aba comunicação.


        O sistema baseia-se em uma arquitetura cliente/servidor e pode ser utilizada de diversas maneiras. O modo mais simples pode ser feito entre dois jogadores, um deles atuando como servidor e o outro como cliente, o servidor deve ser iniciado e em seguida o cliente se conecta a ele, neste caso utiliza-se duas copias do mesmo jogo rodando em 2 computadores diferentes. Algo um pouco mais complexo pode ser feito para múltiplos jogadores, um jogador atuando como servidor e vários jogadores clientes se conectando a ele, neste caso o servidor também deve tratar todas as conexões e atualizar também todos os clientes. Em outro exemplo mais complexo, pode-se desenvolver um aplicativo externo ao 3D Game Builder em qualquer linguagem de programação para atuar unicamente como servidor, todos os clientes devem conectar-se ao servidor que deve tratar todas estas conexões e distribuir todas as mensagens entres os clientes.

        No 3D Game Builder o componente servidor possui somente 2 propriedades, o seu nome e porta onde ele estará aguardando conexões.


        E três possíveis evento para serem tratados:

- OnConnect - Evento que ocorre no momento que um novo cliente se conecta ao servidor.

- OnReceive - Evento que ocorre no momento que o servidor recebe uma mensagem de um dos clientes que estava conectado a ele.

- OnDisconect - Evento que ocorre no momento que um dos clientes se desconecta do servidor.


        O componente cliente é composto por 3 propriedades, o seu nome, o host (endereço ip do servidor) onde o cliente vai se conectar e a porta onde ele deve se conectar.


        O cliente possui os mesmos eventos do servidor, porém com o significado um pouco diferente:

- OnConnect - Evento que ocorre no momento que o cliente consegue se conectar ao servidor.

- OnReceive - Evento que ocorre no momento que o cliente recebe uma mensagem do servidor.

- OnDisconect - Evento que ocorre no momento que o cliente consegue se desconectar do servidor.

        A linguagem script do 3D Game Builder também possui comandos específicos para serem utilizados em conjunto com os componentes para que a comunicação seja efetuada. Os comandos são:

- procedure TCPClientConnect() - Função utilizada para conectar o cliente ao servidor definido em host.

- procedure TCPClientDisconnect() - Função utilizada para desconectar o cliente do servidor onde ele esta conectado.

- function TCPClientRead():String - Função usada para ler o buffer de mensagens (strings) recebidas do cliente. Sempre que uma nova mensagem é recebida pelo cliente ela é armazenada em um buffer (estrutura do tipo fila) e permanece lá até que ela seja lida pelo comando TCPClientRead.

- procedure TCPClientWrite(Msg:String) - Função utilizada para enviar uma mensagem para o servidor que o cliente esta conectado.

- procedure TCPClientClearBuffer() - Função utilizada para limpar o buffer de mensagens recebidas do cliente.

- procedure TCPServerActivate() - Função que ativa o servidor, é necessário que ela seja executada para que o servidor possa receber conexões.

- procedure TCPServerDesactivate() - Função que desativa o servidor, os clientes serão desconectados e ele não recebera mais conexões enquanto não for ativado novamente.

- function TCPServerRead():String - Função usada para ler o buffer de mensagens (strings) recebidas do servidor. Sempre que uma nova mensagem é recebida pelo servidor ela é armazenada em um buffer (estrutura do tipo fila) e permanece lá até que ela seja lida pelo comando TCPServerRead.

- procedure TCPServerWrite(ClientIP:String; Msg:String) - Função utilizada para enviar uma mensagem para um determinado cliente.

- procedure TCPServerWriteToAll(Msg:String) - Função utilizada para enviar a mesma mensagem para todos os clientes conectados ao servidor.

- function IsTCPClientConnected():Boolean - Função que retorna true se o cliente estiver conectado.

- function GetTCPClientHost():String - Função que retorna o nome ou ip do host (servidor) definido no cliente.

- function GetTCPClientPort():Integer - Função que retorna a porta definida no cliente.

- function GetTCPServerPort():Integer - Função que retorna a porta definida no servidor.

- procedure SetTCPServerPort(Port:Integer) - Função utilizada para alterar a porta do servidor.

- procedure SetTCPClientPort(Port:Integer) - Função utilizada para alterar a porta do cliente.

- procedure SetTCPClientHost(Host:String) - Função utilizada para alterar o nome ou ip do host (servidor) do cliente.

        A maneira como será feita troca de mensagens entre o servidor e os clientes depende muito do tipo de jogo, por exemplo, em um jogo de xadrez toda vez que um jogador mover uma das peças ele deve enviar uma mensagem para o oponente passando todas as informações daquela jogada, para isso deve-se criar um protocolo próprio para o formato dessa mensagem para que ela possa ser criada e interpretada.

        No exemplo do jogo de xadrez podemos pensar em um protocolo assim:

        Mensagem = IDPeça|Destino

        onde:

        ID : É um código identificador definido para cada peça.

        Destino : É um código identificador definido para todos os locais do tabuleiro.

        | : Separador.

        Quando um dos jogadores mover uma peça podemos identificá-la pelo seu código identificador e também o local para onde a peça foi movida pelo código identificador do local no tabuleiro, assim podemos facilmente montar a nossa mensagem. Por exemplo:

        Mensagem: “2|16?

        Ou seja, moveu a peça com o ID 2 para o local de ID 16. Montamos a nossa mensagem em uma string e enviamos para o outro oponente (cliente ou servidor). O separador | é usado para conseguirmos separa os dados depois.

        Ao receber a mensagem o oponente deve ler esta mensagem separando os dados para que eles possam ser interpretados. Isso pode ser feito facilmente percorrendo a string procurando pelo caracter separador (|) e guardando o resto em variáveis auxiliares.

        Após separar os dados basta executar o mesmo movimento, sabe-se que a peça de ID 2 deve ser movida para o local de ID 16 do tabuleiro. As peças que vão ser removidas do jogo podem ser tratadas separadamente no cliente e no servidor, visto que a remoção de uma peça depende exclusivamente do movimento das peças.

        Este é o mesmo conceito utilizado para qualquer tipo de jogo, a única coisa que vai mudar é o protocolo, ou seja, o formato das mensagens e os dados que vão ser enviados para o cliente ou servidor. Exemplificando novamente, imagine um jogo 3D onde os personagens andam pelo cenário, o conceito é o mesmo do jogo de xadrez, mas dessa vez vai ser necessário envia a nova posição do jogador (x, y e z) para os outros clientes ou servidor sempre que o jogador se mover, ou então simplesmente o movimento que o personagem precisa executar.

        Este é o básico necessário para se utilizar os recursos para comunicação em rede do 3D Game Builder, agora basta utilizar a sua imaginação e criatividade para criar os seus jogos multiplayer.