1
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E ESTATÍSTICA
CENTRO TECNOLÓGICO
MMORPG: Projeto e Implementação
FLORIANÓPOLIS, 2004
2
LEANDRO RICARDO ORTHMANN
THIAGO CORNELIUS DE LEON
MMORPG: Projeto e Implementação
Proposta de trabalho de
conclusão do curso de
Bacharelado em Ciências da
Computação da Universidade
Federal de Santa Catarina.
ORIENTADOR: MÁRIO A. RIBEIRO DANTAS
FLORIANÓPOLIS, 2004
3
Dissertação submetida ao Colegiado do Curso de Bacharelado em
Ciências da Computação da Universidade Federal de Santa
Catarina como trabalho de conclusão de curso. Comissão
Examinadora formada pelos professores:
Prof. Dr. Mário A. Antônio Ribeiro Dantas
INE / UFSC - Orientador
____________________
Prof. Dr. rer.nat. Aldo von Wangenheim
____________________
INE / UFSC
Banca 1
Prof. Dr. Raul Sidnei Wazlawick
INE / UFSC
____________________
Banca 2
Florianópolis, fevereiro de 2004
4
Àqueles (as) que encontrei na encruzilhada da
vida e, mais que conhecidos, na convivência e no
bem querer, nos tornamos amigos (as)
5
Sumário
1. Introdução ..................................................................................................................... 9
1.1. Objetivos .............................................................................................................. 10
1.2. Justificativa .......................................................................................................... 11
1.3. Organização do Trabalho..................................................................................... 12
2. RPG e MMORPG ....................................................................................................... 13
2.2. Requisitos............................................................................................................. 14
2.2.1. Portabilidade ................................................................................................. 14
2.2.2. Latência......................................................................................................... 15
2.2.3. Tolerância a falhas ........................................................................................ 15
2.2.4. Sincronismo .................................................................................................. 16
2.2.5. Interação com a comunidade ........................................................................ 16
2.2.6. Segurança...................................................................................................... 16
2.2.7. Desempenho.................................................................................................. 17
3. Projeto / Desenvolvimento.......................................................................................... 18
3.1. Introdução ............................................................................................................ 18
3.2. Uma possível arquitetura ..................................................................................... 19
3.3. Computação Distribuída ...................................................................................... 21
3.4. Protótipo do Website ........................................................................................... 23
3.5. Banco de Dados ................................................................................................... 24
3.6. Protótipo do Cliente / Servidor / Controlador...................................................... 26
3.6.1. Ambiente de desenvolvimento...................................................................... 26
3.6.2. Modelagem ................................................................................................... 27
3.6.3. Protocolo de Aplicação ................................................................................. 27
3.6.4. Gerenciamento de Mapas.............................................................................. 28
3.6.5. Gerenciamento de Jogadores ........................................................................ 29
3.6.6. Regras de jogo .............................................................................................. 29
3.6.7. Estratégias de jogo ........................................................................................ 35
3.6.8. Testes ............................................................................................................ 39
3.7. Dificuldades encontradas ..................................................................................... 40
4. Conclusão e Trabalhos Futuros................................................................................... 41
Glossário ......................................................................................................................... 42
Referências...................................................................................................................... 44
Anexos ............................................................................................................................ 45
6
Lista de Figuras
Figura 1 Modelo projetado para a implementação do sistema................................... 19
Figura 2 A utilização de computação distribuída ou clusters pode resolver problemas
de disponibilidade e reduzir custos................................................................................. 22
Figura 3 Eventos que ocorrem fora do campo de visão dos jogadores não são
processados por esses. .................................................................................................... 36
Figura 4 Eventos ocorridos fora do território atual de cada jogador não são
recebidos por esses. ........................................................................................................ 37
7
Resumo
A grande expansão do mercado de entretenimento fez com que surgisse um novo gênero
de jogo, unindo comunidades pela Internet e simulando complexos ambientes virtuais.
O MMORPG vem conquistando espaço entre os usuários de computador, e agregando
valor no mercado de jogos. Esse projeto visa propor um modelo de projeto e
implementação de um MMORPG, analisando dificuldades e características desse tipo
de software.
8
Abstract
The entertaniment market expansion made possible the creation of another kind of
game, bringing together communities and simulating entire virtual worlds through the
Internet. The MMORPG is becoming very popular between computer users and it is
adding value to the game industry. This project aims to consider a model of project and
implementation of a MMORPG, analyzing difficulties and details of this type of
software.
9
1. Introdução
Nos últimos anos têm-se notado o desenvolvimento de um novo tipo de
entretenimento, voltado especificamente para a mídia eletrônica. A evolução dos
computadores permitiu que cada vez mais os jogos eletrônicos, que antes eram vistos
como brincadeiras de criança, se tornassem uma nova fonte de informação,
comunicação e lazer.
Na mesma época do boom dos computadores surgiu um tipo de jogo em que os
jogadores usavam livros e imaginação para interpretar personagens fictícios. O RPG,
como ficou conhecido, logo virou uma febre no mundo inteiro. Diversas empresas
foram criadas especialmente para desenvolver sistemas de RPG, sempre incrementando
e detalhando características. Os mais diversos sistemas e regras, ambientados em
diferentes épocas e mundos, foram criados.
Não tardou muito para que os RPGs ultrapassassem a barreira dos livros e
fossem migrados para o meio eletrônico. Um novo gênero de jogo de computador
surgiu, baseado no RPG de mesa. Porém, apesar de ter as mesmas idéias, conceitos e
situações do antigo RPG, não era possível uma comparação entre os jogos, pois a versão
de computadores não tinha o elemento que tornou o RPG de mesa tão famoso: a
interação entre pessoas. Nos primeiros RPGs para computador, o jogador se limitava a
movimentar seu personagem, realizar ações pré-programadas e lutar contra personagens
comandados pelo computador.
Paralelamente a área de telecomunicações também se desenvolveu durante esse
período. Redes de computadores, impensadas no passado, tornaram-se aos poucos o
padrão para empresas de todos os setores, e posteriormente para usuários domésticos. A
popularização da Internet permitiu que usuários do mundo inteiro passassem a se
comunicar em tempo real, fazendo da rede mundial um novo meio de comunicação,
agregando velocidade, baixo custo e disponibilidade.
Esse avanço fez com que surgissem mais e mais salas de bate papo e programas
de mensagens instantâneas, tudo para melhorar a comunicação de pessoas de todos os
lugares de uma forma fácil e rápida.
De maneira semelhante, jogos de computador foram aproveitando os novos
recursos de comunicação, e tornando-se mais voltados ao objetivo global de interligar
pessoas. Jogos de simulação como o The Sims permitiram que vidas inteiras fossem
10
simuladas através da tela do computador, enquanto comunidades inteiras eram
organizadas através de BBS.
O RPG foi adaptado a essa nova época de comunicação através dos MMORPG,
que literalmente unem milhares de pessoas em um mundo virtual, e cada um pode
interpretar seu personagem, assim como o RPG de mesa.
A proposta desse trabalho de conclusão de curso é a implementação de um
MMORPG, estudo de suas facetas e proposição de estratégias de jogo.
1.1. Objetivos
O objetivo maior do projeto é o estudo, projeto e implementação de um
MMORPG completo e competitivo comercialmente. Porém um jogo de computador,
como a maioria dos softwares semelhantes, é subdividido em várias partes distintas,
cada qual com suas características e dificuldades.
Podemos citar alguns objetivos específicos, baseados nas várias etapas de
desenvolvimento que foram atravessadas:
Estudar
diferentes
tecnologias
de
interconexão
de
computadores, com ênfase em computação distribuída,
clusters e problemas relacionados aos serviços atuais;
Avaliar os sistemas atuais com função semelhante, tanto na
área de jogos quanto em outras áreas;
Propor um modelo de implementação de uma solução que
supra as necessidades e requisitos desejáveis de uma
aplicação utilizando o modelo MMORPG;
Estudar Sistemas de Gerenciamento de Banco de Dados
próprios para o uso simultâneo de diversas aplicações
distintas, fornecendo confiabilidade, desempenho e segurança;
Construir
um
protótipo
seguindo
o
modelo
de
desenvolvimento estudado;
Testar e analisar o desempenho do protótipo, nas mais
diferentes e adversas condições de conexão.
11
1.2. Justificativa
Economicamente o setor de entretenimento eletrônico vem crescendo cada
vez mais, principalmente na área de computadores. Bilhões de dólares são
movimentados nesse mercado, e tudo indica que a situação comercial dos jogos
continuará a crescer.
Nos jogos usuais , o consumidor paga o preço de um jogo e assim pode
jogá-lo, individualmente ou pela Internet com outros compradores do produto. Já na
maioria dos MMORPGs não há cobrança pelo software em si, e sim pelo direito de
utilizar o serviço mensal. Isso porque todo o sistema é feito por servidores que
gerenciam mundos, histórias e jogadores. Sem esse elemento central a história não pode
continuar, e o software instalado nos computadores dos jogadores perde a
funcionalidade.
O fato de o jogo poder ser distribuído livremente também evita a pirataria,
um dos grandes problemas no Brasil atualmente. A receita pode ser obtida de diversas
maneiras:
Cobrando uma taxa mensal dos assinantes;
Vendendo serviços de suporte técnico;
Solicitando doações e privilegiando doadores com recursos
exclusivos;
Utilizando propaganda no jogo;
Etc.
O apelo comercial chega a ser tão explícito que em alguns casos, como no
jogo Everquest, usuários vendem em leilões online como o eBay propriedades virtuais,
que só podem ser usufruídas dentro do próprio jogo. A economia do Everquest é tão
complexa que é comparada à economia de um pequeno país.
Os jogos são um dos tipos de software que mais utilizam tecnologias de
ponta, nas mais diversas áreas: redes, computação gráfica, multimídia, segurança e
armazenamento. Times inteiros de artistas e programadores são necessários para a
construção de um jogo nos padrões atuais, o que acaba elevando o custo de produção e
conseqüentemente o preço para o consumidor final.
12
Como estamos fazendo o trabalho em dupla, procuramos focar nossos
esforços no setor de tecnologia de Redes, já que o principal atrativo do sistema
desenvolvido é a capacidade de comunicação com outras pessoas através da Internet.
Apesar disso, tudo pode ser incrementado, desde o desenho dos personagens até a
inclusão de vídeos e efeitos especiais.
Além de todos os motivos comerciais e tecnológicos, sempre fomos fãs de
jogos eletrônicos, assim como de RPG. Isso nos deixou mais à vontade em trabalhar
com o tema e também evitou a pesquisa preliminar sobre os fundamentos de jogos
eletrônicos. A possibilidade de trabalhar em um projeto como esse nos deu ânimo para
escolhermos esse tema.
1.3. Organização do Trabalho
O trabalho foi dividido em cinco partes, para melhor guiar o leitor através do
tema escolhido e dos problemas e estratégias adotadas.
O primeiro capítulo é uma introdução sobre o RPG e dos objetivos desse
trabalho, com justificativa. Após, será explicado em detalhes o sistema de RPG e
MMORPG, para que o leitor entenda qual é o resultado esperado desse tipo de
aplicação. O terceiro capítulo parte especificamente para o projeto e implementação do
sistema, que é o objetivo principal desse trabalho. O quarto capítulo deixa em aberto
algumas possibilidades de continuação do projeto, assim como dá um desfecho para o
trabalho. Finalmente serão apresentadas referências que
desenvolvimento desse projeto.
utilizamos para o
13
2. RPG e MMORPG
RPG é tipo de jogo surgido nos anos 70 com o lançamento de Dungeons and
Dragons, criado por Gary Gygax em 1972. Trata-se de um jogo de interpretação de
papéis, onde os jogadores (geralmente 4
8) criam personagens fictícios em um mundo
imaginado pelo Mestre do jogo. Esses personagens possuem diversas características e
habilidades, como inteligência, lábia, aptidão com armas, magias, etc. O jogo se
desenrola à medida que o Mestre conta uma história em que os jogadores participam,
interpretando seus personagens.
Dependendo apenas da imaginação dos jogadores e de um conjunto de
regras, o RPG difundiu-se pelo mundo através de diversas empresas, que criaram
mundos completos nos mais diversos temas: idade média, ficção científica, sobrenatural
e até cenários históricos são revividos em detalhes pelos jogadores. A complexidade do
jogo depende apenas da criatividade do Mestre e dos jogadores.
Atualmente o RPG, além de entreter, é usado com fins educacionais.
Professores utilizam o método para melhor fixar conteúdos históricos em seus alunos,
incentivar pesquisas específicas e outros objetivos, tudo de uma forma interativa e
divertida.
Com a popularização dos computadores, usuais jogadores de RPG e de
outros jogos viram o potencial comunicativo dos computadores e se organizaram em
BBS, comunidades inteiras organizando e participando de partidas dos mais diversos
jogos. Surgiu o PBEM, onde jogos de guerra e tabuleiro eram jogados por e-mail.
A aceitação desses tipos de jogos, juntamente com jogadores de RPG ávidos
por aventuras online, fez com que fosse criado o gênero MUD. Ele possibilitou que
jogadores geograficamente distribuídos pudessem incorporar um personagem (também
conhecido como Avatar) em um mundo alternativo, onde as regras são definidas por
cada Mestre de jogo. A evolução dos MUDs permitiu que o número de jogadores
simultâneos progredisse a uma taxa espantosa, chegando ao ponto de milhares de
jogadores estarem conectados ao mesmo tempo no mesmo mundo fictício, cada um
interpretando um Avatar e participando de aventuras dinâmicas. Rapidamente um novo
termo começou a se popularizar: MMORPG.
Diversos títulos são lançados usando o sistema MMORPG. Entre eles,
podemos citar a série Ultima, criado pela Origin; Everquest, da Sony; Asheron s Call,
14
da Microsoft, entre outros. Além dos títulos mais conhecidos, centenas de outros jogos
são lançados no mercado a todo instante.
2.2. Requisitos
Para a construção de um artefato de software seguindo o modelo MMORPG em
tempo real, algumas características devem ser levadas em consideração:
Portabilidade
Latência
Tolerância à falhas
Sincronismo
Interação com a comunidade
Segurança
Desempenho
Etc.
A seguir é detalhada cada característica desejável no projeto.
2.2.1. Portabilidade
Uma das metas de um software baseado em comunidades é a popularidade e
fácil acesso. A interface para o usuário deve ter a capacidade de ser executada em
diferentes plataformas e sistemas.
Existem várias soluções para essa questão. Uma delas é o desenvolvimento de
diferentes implementações baseadas em plataformas específicas, assim aproveitando
melhor o hardware e capacidades de cada sistema. Essa solução pode dificultar o
processo de manutenção e incremento de recursos, pois cada mudança feita no jogo
deve ser espelhada para todas as suas versões, cada qual desenhada para uma arquitetura
específica. A vantagem dessa solução é o desempenho, pois cada implementação vai
tirar o máximo proveito da plataforma em que está desenvolvida.
Outra possibilidade é a utilização de uma linguagem não dependente de
plataforma, como Java. Apesar de ter menor desempenho, essa abordagem permite que
mudanças sejam feitas de uma maneira fácil e rápida, sem alterações específicas de
plataforma.
15
2.2.2. Latência
Em todo o sistema baseado em tempo real é muito importante termos algum tipo
de Qualidade de Serviço regendo a comunicação dos processos. Não é viável que algum
jogador fique impossibilitado de se comunicar com o servidor por algum problema de
latência. A performance em tempo real e tempo de resposta só podem ser garantidas até
um certo ponto[12].
Por definição, latência é a quantidade de tempo decorrido para um evento
receber uma resposta [3]. Por exemplo, quando um usuário efetua um comando de rede
em sua máquina local, o tempo até ele receber uma resposta do servidor é chamado de
latência.
Baixo tempo de latência é vital para que não ocorram problemas de sincronismo,
integridade e lentidão.
2.2.3. Tolerância a falhas
Esse será um ambiente onde um número muito grande de jogadores estará
conectado ao mesmo tempo, e suas ações influenciam todo o estado do mundo a todo o
momento. O sistema deve ser capaz de suportar falhas e perdas de conexão, evitando
que um jogador desconectado possa influenciar o estado global do jogo e as ações de
outros jogadores.
Como exemplo podemos citar dois jogadores negociando armaduras na feira
local. O jogador A está enviando sua armadura para o jogador B, no exato momento em
que o jogador B perde a conexão por alguma eventualidade qualquer. A tolerância a
falhas deve agir para evitar que os dois jogadores permaneçam com a armadura (caso o
jogador B tenha recebido a armadura, porém não tenha ainda enviado uma confirmação
de recebimento), ou então nenhum dos dois ficar com o item.
16
2.2.4. Sincronismo
O sincronismo é uma das principais características nesse tipo de aplicação, e
rege que o estado dos mundos deve ser transmitido de mesma forma para todos os
jogadores.
Não é viável, por exemplo, que um jogador esteja observando o mundo de uma
forma enquanto outro jogador o veja de forma diferente. A dificuldade de se trabalhar
com o sincronismo é que todos os jogadores estarão alterando o estado do mundo a
todos os instantes.
2.2.5. Interação com a comunidade
Além do jogo em si, é preciso existir uma forma de divulgá-lo e interagir com a
comunidade. Com a popularização da Internet, nada mais óbvio do que pensar em um
website como meio de propagação e informação do sistema.
A idéia é que exista um portal em que internautas e usuários possam ter acesso a
diferentes dados do jogo, como por exemplo:
Atualizações e Patches;
Notícias;
Skins para o sistema;
Explicações sobre o jogo;
História dos mundos;
Estatísticas gerais;
Melhores jogadores;
Intrigas locais;
Informação de Clãs;
Enciclopédias de referência com equipamentos, magias, etc.
Esse website deve estar conectado no mesmo banco de dados principal do jogo,
para poder gerar dados em tempo real e fazer modificações concisas.
2.2.6. Segurança
Impossível pensar em um sistema online sem segurança apropriada. No caso do
modelo estudado, podem ocorrer vários tipos de ataque prejudiciais ao sistema:
17
Ataque direto ao servidor do sistema, principalmente pelo
método DoS. Isso causa a interrupção do jogo, pois todos os
jogadores conectados param de receber e enviar informações;
Ataque direto ao servidor que hospeda o website, também por
DoS. Apesar de o problema não afetar os jogos em progresso,
ele interrompe as conexões dos internautas ao website;
Invasão ao hospedeiro do website, desfigurando suas páginas
ou excluindo conteúdo;
Acesso ao banco de dados, permitindo a modificação de
dados a favor ou contra jogadores, ou mesmo com intenções
maliciosas de prejudicar o sistema como um todo.
Criação e modificação de mensagens enviadas para o servidor
ou clientes, possibilitando que informações incorretas sejam
processadas pelas entidades envolvidas.
Interceptação de dados em qualquer ponto da rede, o que
poderia causar a captura de dados sigilosos como senhas e
mensagens secretas entre clãs.
2.2.7. Desempenho
É evidente que todo software deve levar em consideração seu desempenho nos
diversos computadores em que pretende ser executado.
Isso é especialmente verdade nesse caso, quando é preciso atingir um número
grande de pessoas. Unido à portabilidade, o alto desempenho em computadores mais
antigos pode fazer com que mais pessoas possam desfrutar do software.
18
3. Projeto / Desenvolvimento
3.1. Introdução
Após termos estudado o modelo e requisitos do projeto, vamos partir para
métodos de implementação, visando as atuais tecnologias e também os problemas e
dificuldades encontrados.
É bom lembrar que softwares de entretenimento (principalmente jogos
eletrônicos) fazem parte de um dos tipos de programas que mais requer profissionais
capacitados, nas mais diversas áreas. Um jogo usual é implementado em blocos, com a
separação de times de desenvolvimento. Assim, para o mesmo projeto, podem ser
necessárias várias funções, às vezes com vários profissionais realizando a mesma
função. Em um jogo comercial, por exemplo, diversas são as áreas de atividade
necessárias:
Diretor
Programador
Projetista de Níveis
Produtor
Projetista de Modelos
Animadores
Supervisor de Efeitos Especiais
Projetista de Som
Compositores
Escritor
O que acontece em pequenas empresas desenvolvedoras de jogos é a união de
várias tarefas por um profissional, diminuindo a qualidade porém reduzindo custos.
O modelo que iremos apresentar leva em consideração semelhante equipe, para
que o resultado possa ser competitivo comercialmente.
19
3.2. Uma possível arquitetura
A maneira pensada para cumprir os requisitos é a mostrada abaixo:
Figura 1
Modelo projetado para a implementação do sistema.
Esse modelo propõe a presença de cinco entidades:
Servidor:
O servidor será encarregado de executar um programa específico para controle e
execução dos mundos. Todo o processamento e manutenção do estado de objetos dos
20
mundos virtuais serão feitos pelo programa rodando no servidor (doravante chamado
simplesmente de servidor ).
O servidor também será responsável por todos os movimentos do mundo que
não forem efetuados pelos jogadores. Isso inclui movimento de NPCs, monstros, etc.
Rotinas periódicas de manutenção também são executados pelo servidor.
O link de acesso que conectará o servidor à Internet deve ser adequado para o
tráfego de um número grande de pacotes por segundo, à medida que mais e mais
clientes se conectem ao servidor central.
Cliente:
O programa cliente será como uma janela de comunicação entre o jogador e o
mundo rodado no servidor. A idéia é que cada usuário tenha instalado uma cópia do
cliente em seu computador. Ele trará consigo todos os recursos do jogo, incluindo
objetos, gráficos, sons, bibliotecas e interface adequada. Porém, o cliente não funciona
sozinho
ele precisa estar conectado ao servidor central, que lhe dará as coordenadas de
o quê mostrar para o jogador.
Banco de dados:
O banco de dados escolhido terá que se comunicar tanto com o servidor de
aplicação quanto com o website. Com isso, espera-se que o número de conexões
simultâneas a esse banco seja muito grande: a cada movimento ou alteração de
jogadores, o banco de dados será atualizado. Cada visita ao website também implica em
alterações no banco de dados.
É ideal também que seja escolhido um Sistema de Gerenciamento de Banco de
Dados compatível com as linguagens de desenvolvimento do servidor e do website.
Website:
Seguindo o mesmo modelo especificado anteriormente, o website será a ponte
de comunicação entre o cliente e os dados do jogo, suas regras e informações gerais. Irá
acessar o mesmo banco de dados do servidor, garantindo que os dados mostrados ao
internauta correspondam às informações mais novas geradas pelo jogo, rodando no
servidor.
21
Controlador:
O controlador é um programa com mais privilégios do que o programa cliente,
porém funciona de maneira semelhante a este: o usuário do controlador pode visualizar
o mundo executado no servidor e interagir com ele.
Mas ele não se restringe a isso: o controlador tem funções especiais de
gerenciamento e controle. O controlador pode possuir diversas funções extras, como por
exemplo:
Habilidade de inserir no jogo objetos ou monstros;
Banir ou prender jogadores;
Controlar um NPC para interagir com jogadores de uma
maneira personalizada;
Enviar mensagens para algum jogador ou para vários, em
forma de broadcast;
Guiar os jogadores através de calabouços ou labirintos;
A principal função do controlador é controlar o mundo e dar continuidade à
história, de maneira semelhante ao mestre de jogo dos RPGs de mesa. Apenas
administradores do sistema teriam acesso à esse programa, e vários controladores
podem moderar o mesmo mundo.
3.3. Computação Distribuída
O grande atrativo dos MMORPGs é a capacidade de unir um número muito
grande de jogadores, simultaneamente. Cada um deles terá sua própria visão, ações,
itens, relacionamentos, etc. Vale lembrar que o servidor será o responsável por todo o
processamento do jogo, cabendo aos clientes simplesmente enviar e receber mensagens
e mostrar o resultado para o jogador (em uma interface gráfica).
Com isso em mente, estima-se que o aumento do número de conexões de
clientes no servidor possa fazer com que o último não consiga atender a demanda de
informações que devem ser processadas.
Existem diversas soluções para melhorar a disponibilidade do servidor e
minimizar problemas decorrentes da alta demanda. Uma delas é a utilização de
supercomputadores com capacidade de processamento compatível com o número
22
máximo de clientes configurado. Infelizmente essa solução tem alto custo e todos os
problemas envolvendo o uso de supercomputadores.
A solução analisada por esse projeto é o uso de computação distribuída entre um
número n de servidores, como mostrado a seguir:
Figura 2
A utilização de computação distribuída ou clusters pode resolver problemas
de disponibilidade e reduzir custos.
Nesse modelo o servidor é na verdade um conjunto de vários computadores,
todos trabalhando em conjunto com os clientes e com o banco de dados, e também entre
si.
23
O fato de os computadores precisarem se intercomunicar em velocidades
extremamente rápidas nos faz pensar em uma solução de computação distribuída ou
computação paralela.
A comunicação de computadores é muito difundida hoje em dia em forma de
redes locais corporativas e até domésticas. Nessas redes, processos são executados
localmente por cada máquina, e a comunicação ocorre entre os processos, geralmente
envolvendo pouca quantidade de dados. Esse modelo funciona muito bem, pois não há
compartilhamento de recursos entre os computadores. A pouca informação trafegada
pode muito bem ser gerenciada em redes locais, como Ethernet. Nesse caso a
velocidade é baixa
atualmente as mais altas giram em 1Gb/s, no caso de Gigabit-
Ethernet.
Ao tratar de servidores compartilhados, porém, a abordagem deve ser diferente.
Todos os servidores devem trabalhar conjuntamente, compartilhando recursos como
memória e processador. Além disso, todos devem ter comunicação total ao banco de
dados, e seu estado deve ser atualizado a cada alteração realizada.
Diversas metodologias podem ser vistas para desenvolver esse tipo de idéia,
incluindo clusters e grids computacionais. Cada uma das possibilidades envolve muito
estudo e pesquisa, e trabalhos inteiros de graduação podem ser feitos só falando sobre o
projeto e instalação desse tipo de processo.
Apesar de ser uma tecnologia muito interessante e funcional, não tivemos tempo
útil para estudá-la e implementá-la. Pode-se pensar no desenvolvimento de soluções
semelhantes como trabalhos futuros. Para mais informações sobre sistemas distribuídos
leia [1] e [14].
3.4. Protótipo do Website
O protótipo do website construído traz pouca funcionalidade, pois a maioria dos
recursos a disponibilizar não dependem de desenvolvimento técnico, sendo mais
associados à comunidade: clãs, estatísticas de acesso, material do jogo, etc.
Acreditamos que o desenvolvimento completo do website só será necessário
quando a base do jogo for concluída. Com o aumento da comunidade ao redor do
projeto, pode-se pensar em diversos outros recursos.
24
O sistema presente no website deve ser dinâmico para refletir o estado do mundo
e dos jogadores em tempo real, além de minimizar trabalho com manutenção e
desenvolvimento de novas ferramentas online.
Essa característica faz com que tenhamos que escolher alguma linguagem Server
Side para garantir a segurança e realizar algoritmos mais complexos, inapropriados para
linguagens Client Side como Javascript. A linguagem de desenvolvimento escolhida foi
PHP, pelas seguintes características:
Ter forte acoplamento com o banco de dados MySql;
É uma linguagem gratuita;
Está disponível no sistema do Departamento de Informática e
Estatística da UFSC;
Existe uma gama de ferramentas com código aberto
disponíveis para utilização;
A documentação disponível é extensa e completa.
A grande comunidade em torno da linguagem faz com que a
resolução de problemas seja facilitada através de fóruns
online e FAQs.
3.5. Banco de Dados
O sistema de gerenciamento de banco de dados escolhido foi o MySQL, uma
solução gratuita para o sistema SQL. Assim como o PHP, é uma linguagem gratuita,
com alto desempenho e grande integração com várias outras tecnologias baseadas em
internet.
O MySQL está se tornando cada vez mais popular entre desenvolvedores de
sites, e principalmente pelo website ter sido desenvolvido em PHP essa linguagem será
utilizada nesse protótipo.
A modelagem do banco de dados foi feita baseada nas regras de jogo, que
podem ser expandidas à medida que os elementos de RPG vão sendo detalhados.
Cada usuário (que pode ser cadastrado pelo website) pode possuir n
personagens.
Tabela user
25
Campo
Descrição
id
Identificador único de usuário
username
Nome de usuário único
password
Senha para acesso
full_name
Nome completo do usuário
email
E-mail do usuário
Cada personagem terá inúmeras características, assim como uma coleção de
itens armazenados. A maioria dos campos é nomeada com abreviaturas de atributos,
para que fique conciso com outros sistemas de RPG.
Tabela
character
Campo
Descricao
id
Identificador único do personagem
user_id
Identificador do usuário a qual esse personagem
pertence
name
Nome do personagem único
race
Raça do personagem (humano, elfo, fada, etc.)
class
Classe ou profissão do personagem (guerreiro, mago,
ladrão, etc.)
level
Nível do personagem. Quanto maior, maiores são as
suas habilidades.
model
O modelo gráfico de avatar associado ao personagem
hp
Hit Points: pontos de vida
mp
Magic Points: pontos de magia
atk
Ataque: força de ataque
def
Defesa: capacidade defensiva
spd
Velocidade: capacidade de esquiva
reputation
Reputação do personagem, que depende dos seus atos
durante os jogos
last_map
Último local visitado. Útil para a determinação de um
26
ponto de partida quando o jogo é iniciado
times_killed
Número de vezes em que o personagem foi morto
xp
Experiência adquirida; é usada para incrementar o nível
do personagem.
Além de dados sobre os usuários e seus personagens, são armazenadas
informações sobre cada mundo e estatísticas gerais.
O banco de dados também é necessário para armazenar tabelas de ferramentas
específicas utilizadas no website, como fóruns, índices de imagens, sistemas de
anúncios, etc.
3.6. Protótipo do Cliente / Servidor / Controlador
Com base no modelo de projeto desenvolvido, foi implementado um protótipo
do sistema, que é separado em Cliente e Servidor.
3.6.1. Ambiente de desenvolvimento
A comunicação entre o servidor e o cliente é feita através de Sockets. Foi
utilizado o pacote do Java nio, que possui um desempenho de entrada/saída superior que
o pacote io do Java.
Os dados passados entre o servidor e o cliente são objetos da classe Mensagem
ou alguma classe filha dela. A mensagem padrão possui um campo que identifica a ação
realizada, um campo identificando o usuário realizador da ação, um identificador de
prioridade da ação e um conjunto estático de parâmetros adicionais que possuem uma
finalidade de acordo com a ação. Existe um outro tipo de mensagem que ao invés de um
conjunto de parâmetros ele possui uma string.
Com a identificação de prioridade da mensagem, o cliente e o servidor podem
escalonar o processamento com base na prioridade da mensagem. Com isso uma
mensagem informando o movimento de um personagem, é processada antes de
mensagens de fala, que possuem prioridade baixa e que não afetam o sincronismo
espacial do mundo bem como a integridade das propriedades (por exemplo: estar vivo)
de um personagem.
27
3.6.2. Modelagem
O protótipo foi desenvolvido utilizando vários modelos de implementação, para
que fossem definidos elementos do jogo. Podemos dividir o projeto em grandes partes,
efetivamente implementados como pacotes. Iremos resumir cada um destes a seguir:
Beings: contém toda a parte de seres vivos, como
personagens, monstros, NPCs, etc.
Itens: descrição de itens, equipamentos e objetos em geral.
Efeitos especiais desses itens (como veneno, capacidade
curativa, etc) são implementados no pacote Eventos.
Gerenciadores: neste pacote estão contidas classes de gerência
de vários recursos do jogo, como jogadores, mapa, eventos,
etc.
Eventos: descreve os diferentes fenômenos que podem ocorrer
com jogadores e monstros, como o efeito flamejante de uma
espada mágica ou a picada de um animal peçonhento.
Transações comerciais também são implementadas por
métodos específicos.
Mapa: contém classes específicas para a criação de terrenos e
mapas, suas propriedades e interação com avatares. A
interação do mapa com os jogadores é feita pelo pacote
Gerenciadores.
Utils: definições de constantes utilizadas.
3.6.3. Protocolo de Aplicação
A comunicação entre o servidor e o controlador / cliente é um dos aspectos mais
importantes do projeto, pois todo o sistema é executado remotamente, à partir do mundo
que se passa no servidor. Basicamente o meio de comunicação dessas entidades é feito
através de mensagens, ou blocos de texto seguindo regras determinadas.
Foi desenvolvido um protocolo para a passagem de mensagens entre as
entidades, buscando facilitar a estruturação e flexibilidade das mensagens.
28
A classe Mensagem atua como um modelo para o envio de mensagens, contendo
os atributos básicos e necessários para que as entidades possam enviar o mínimo de
dados para relatar uma ação.
Como é uma classe, a Mensagem pode ter subclasses específicas para cada tipo
de ação que se tornar necessário, herdando todos os atributos básicos das mensagens
usuais.
A classe Mensagem tem os seguintes atributos:
jogadorId: provê a identificação do remetente da mensagem;
ação: provê o identificador da ação realizada;
prioridade: identifica a prioridade da ação. Algumas ações,
como requisição de mapa e movimentação são mais
importantes que outras, como bate papo entre jogadores.
Mensagens com maior prioridade são executadas primeiro,
caso haja sobrecarga no servidor.
parametros: array de de variáveis com os parâmetros da ação
escolhida.
Os métodos dessa classe são apenas para o acesso dos atributos.
Cada jogador tem um canal exclusivo de comunicação com o servidor (thread).
Isso garante que a comunicação do servidor com um cliente não atrapalhe sua
comunicação com outro cliente.
3.6.4. Gerenciamento de Mapas
O protótipo foi desenvolvido com uma janela de visualização do jogo em 2
dimensões, onde os personagens e objetos são vistos perpendicularmente ao chão, como
uma vista aérea.
A modelagem do mapa foi feita através de matrizes, onde cada célula da matriz
contém um fragmento de terreno básico, como grama, pedras, água, lava, etc. Esses
pequenos pedaços fazem o mapa geral do território.
Adicionalmente, cada fragmento de terreno contém uma pilha de objetos. Esses
objetos podem ser de diversos tipos:
Avatares, como jogadores e NPCs;
Objetos de cenário, como árvores, pedras, etc;
29
Itens, como espadas, dinheiro, pergaminhos;
Modificadores de terreno, como chamas e efeitos especiais;
Além disso, terrenos podem ter atributos, como a dificuldade de travessia por
parte dos jogadores ou mesmo seu bloqueio total (no caso de uma floresta densa ou os
muros de uma cidade, por exemplo).
3.6.5. Gerenciamento de Jogadores
A classe GerenciadorJogadores é utilizada pelo servidor para armazenar e
controlar os jogadores conectados. Uma instância dessa classe é criada no momento em
que o servidor é iniciado, e ela atua como intermediário entre jogadores, permitindo a
troca de mensagens e evitando conflitos nessa transmissão.
Para a criação do Gerenciador, foi utilizado o Design Pattern Filho Único , o
que permite que exista apenas uma instância de sua aplicação no servidor. Assim, todo o
jogador acessa o mesmo gerenciador.
3.6.6. Regras de jogo
1.
NPCs
Os NPCs são personagens não controlados por jogadores, ou seja, são
personagens controlados pelo computador. Eles podem ser divididos em dois grupos, os
NPCs hostis (monstros em geral) e NPCs não hostis (são os personagens que vendem
itens em suas próprias lojas, que desejam boas-vindas nos portões das cidades e os que
dão algumas dicas para os jogadores).
Os NPCs não hostis possuem um comportamento determinado: para um jogador
se comunicar com ele, basta que o mesmo diga algumas palavras-chave reconhecidas
pelo NPC. Para iniciar uma conversa com o NPC, por exemplo, basta que o jogador
diga a palavra chave oi que o NPC responda ao cumprimento, marcando o início da
conversa com o jogador. Caso algum outro jogador tente iniciar uma conversa com o
mesmo NPC, esse jogador será adicionado à uma fila de espera do NPC (que possui um
tamanho máximo, e jogadores distintos).
30
Cada NPC tem sua utilidade na trama do jogo. Para finalizar a conversa basta
falar tchau ou sair do campo de atendimento do NPC (o campo de atendimento é uma
área delimitada ao qual o NPC ouve os jogadores). Como exemplo de conversa suponha
o jogador com o personagem Eriorn e o NPC Seimour que vende armas:
Eriorn: OI
Seimour: Olá! O que você deseja?
Eriorn: COMPRAR ESPADA
Seimour: A espada custa 12 peças de ouro! Desejas comprar?
Eriorn: SIM
Seimour: Obrigado! Deseja mais alguma coisa?
Eriorn: TCHAU
Seimour: Até logo! Volte sempre!
No exemplo acima, o jogador utilizou as palavras-chave para se comunicar com
o NPC. Caso o jogador fale algo que o NPC não entenda, a frase é simplesmente
ignorada. O reconhecimento das frases é facilmente feita através de expressões
regulares, pois a linguagem é fechada, com poucas palavras, que possuem significados
próprios. Os NPCs não hostis não podem ser atacados.
Regular Expressions are the key to powerful, flexible and efficient text processing.
Regular expressions themselves, with a general pattern notation almost like a mini
programming language, allow you to describe and parse text. With additional support
provided by the particular tool being used, regular expressions can add, remove,
isolate, and generally fold, spindle, and mutilate all kinds of text and data. [9]
Os NPCs hostis que compõe o quadro de monstros e seres malignos são
enfrentados pelos jogadores, formando boa parte da diversão do jogo. Esse tipo de NPC
possui uma IA (inteligência artificial) de forma diferente aos NPCs não hostis: eles não
conversam com os jogadores (a grande maioria dos NPCs são monstros que não sabem
falar) e sim os atacam (que é o objetivo principal deste tipo de NPC).
Os NPCs hostis atacam o personagem do jogador a primeira vista, que será seu
alvo de ataques até matá-lo ou não conseguir alcançar o personagem (provavelmente
porque o jogador fugiu do campo de visão do NPC ou porque não existe caminho livre
entre o NPC e o personagem do jogador). Pode-se facilmente mudar o alvo do monstro
para ao invés de atacar apenas personagens jogadores atacar qualquer ser do mundo,
31
isso poderia dar mais realidade ao mundo com monstros se atacando também, mas como
é muito comum haver lugares com muitos monstros juntos, isso deixaria de ser
interessante ao jogador que chegaria no local e os monstros estariam batalhando entre si
e se matariam sozinhos, acabando com a diversão do jogador.
Quando os NPCs hostis são derrotados, o jogador que o matou ganha pontos de
experiência (quantidade determinada pelo NPC) e pode deixar alguns itens junto ao seu
corpo, uma espécie de despojo de batalha.
2.
Personagens Jogadores (PC player character)
Os personagens jogadores são os principais atores do mundo , são eles que
fazem a história do jogo. Esses personagens, como são controlados pelos jogadores,
possuem atitudes/comportamentos de acordo com a vontade do jogador, criando assim
uma população de indivíduos diferentes, cada qual com seu temperamento e tendências.
Por exemplo, um jogador pode ser cruel e matar outros jogadores em áreas mais
desertas para roubar seus pertences, ou então ser um exemplo de virtude ajudando
outros jogadores em seus problemas - desde o entendimento das regras do jogo até ajuda
mais direta em uma batalha. Além disso, pode-se fazer com que o personagem vire um
vendedor ambulante e tente vender para outros jogadores alguns de seus itens por
preços mais amigáveis do que com os vendedores NPC s.
Com as falas, os personagens jogadores podem conversar entre si ou mesmo
contara histórias de suas aventuras em tavernas e praças públicas. Cada PC possui
alguns atributos que definem o quão poderoso ele é: os principais são o nível de
experiência e a habilidade com armas.
Nível de experiência: influencia nos personagens os seguintes atributos, sua
quantidade de pontos de vida e a quantidade de peso que conseguem carregar. O nível
de experiência aumenta de acordo com a quantidade / dificuldade de monstros vencidos.
Habilidade com armas: influencia a quantidade de dano que o personagem
consegue causar. Basicamente ele funciona como um catalisador sobre a arma no
ataque. Essas habilidades são atributos importantes na hora de calcular o dano causado
por um ataque.
Os PC s podem carregar uma armadura, uma arma e dois itens - contanto que o
tenham força suficiente para carregá-los.
32
Algumas ações que os PC s pode fazer são:
Olhar;
utilizar algum item;
atacar algum ser do mundo;
falar;
vender algum item que possua;
pegar algum item que esteja no chão ou em um corpo de um
ser moribundo e colocar em seu espaço de itens (se suportar
o peso adicional e possuir espaço livre em seu inventário para
o item).
Das ações acima, a ação de olhar pode ser feita sem haver comunicação com o
servidor, pois o PC só poderá olhar objetos que estão em seu campo de visão. Como o
programa cliente já tem essas informações, essa ação não muda o estado do mundo, e
portanto não precisa do servidor.
Quando um PC morre é transportado de volta a área inicial do jogo com os
pontos de vida completos e possivelmente com a perda de algum item. O roubo de itens
é o único incentivo que se tem à existência de PKs (Player Killers, jogadores que matam
jogadores), pois não existe ganho de experiência. Essa restrição ocorre para evitar o
massive player killing (assassinato massivo de jogadores), uma atitude mal vista por
jogadores que procuram diversão, que estes possuem preferência na criação de regras do
jogo.
Comumente em MMORPGs a transação (venda/troca) de itens é feita com um
PC colocando o item no chão enquanto o outro PC faz o mesmo e assim cada um pega o
item do outro. O problema é que essa forma não é segura, pois pode aparecer um outro
PC e pegar os itens antes, ou mesmo trapaça por parte de um dos lados da transação. A
venda segura é feita da seguinte forma: um PC informa ao outro que quer fazer uma
transação com o item desejado em uma janela diferente da do mundo , o outro PC pode
olhar o item, mas não pode pegá-lo, e este então pode colocar um item na transação (por
exemplo, moedas), a partir de então os itens da transação estão fechados, não se pode
mudar o item depois de colocado, e se os dois PC s confirmarem a transação ela ocorre,
caso contrário à transação é cancelada.
33
Quando o jogador não estiver online, seu personagem não aparecerá no mundo.
E quando o jogador conecta, seu personagem voltará a aparecer no mundo, na mesma
posição de quando desconectou da última vez que jogou.
3.
Combates
Foi citado anteriormente que os seres do mundo podem lutar entre si, mas não
havia sido comentado ainda como isso funciona. Isto será relatado nesta seção.
Os ataques são baseados em alguns atributos do atacante, como a arma utilizada
e sua habilidade com a arma como no caso dos PC s e em alguns NPCs ou pela
definição do poder de ataque no caso da maioria dos NPC s. Enquanto a defesa de um
ataque é baseada na armadura no caso dos PC s ou na resistência da pele no caso dos
NPC s.
Quando um PC ou NPC informa ao servidor que deseja atacar um personagem, é
criado um evento de ataque do PC/NPC sobre o personagem atacado no servidor. O
evento ataque em tempos em tempos faz um ataque sobre o atacado caso este esteja ao
alcance do ataque. Note que mesmo se o jogador estiver com lag, os ataques ocorrerão
de forma correta, sem atrasos. O ataque termina com a morte de um dos lados ou com o
cancelamento do ataque por parte do atacante.
Para impedir que um jogador escape de um combate por meio da desconexão,
não é possível sair do jogo enquanto se está sofrendo um ataque ou atacando. Caso o
jogador saia mesmo assim (desconectando ou fechando o jogo), seu personagem
continuará online no jogo enquanto o combate não tiver acabado. Como exemplo
suponha que um personagem jogador de nível baixo que está andando por uma caverna
que não conhecia até então e se depara com um dragão que está preste a atacá-lo, como
dragões são seres poderosos a derrota será certa, e para impedir que seu personagem
morra o jogador simplesmente sai do jogo e seu personagem não chega a ser atacado,
isto obviamente não deveria acontecer, e seu personagem deveria sofrer as
conseqüências por sua incautela. Como efeito da impossibilidade de escapar de um
ataque, as aventuras dos jogadores se tornam mais excitantes com a possibilidade da
morte a cada passo que é dado, por exemplo, em um covil de monstros.
34
4.
Itens
Todo item possui um peso, um preço (utilizado pelos NPCs mercadores) e um
nome. Os itens são todo tipo de bugiganga que se pode encontrar no jogo, os mais
importantes são os equipamentos, que serão utilizados pelos PC s.
Os itens do jogo são divididos em algumas categorias, os mais importantes são:
armas, armaduras, poções, sacolas, moedas e comida.
As moedas são a unidade monetária do mundo do jogo. Com elas se pode
comprar equipamentos, comida, poções e outros itens. Conseguidos pelos personagens
jogadores nos pertences de PC/NPCs mortos ou através da venda de itens que possui.
Armas e armaduras são os equipamentos que os PC s utilizam para se preparar
para o combate, cada uma possui atributos que as tornam mais poderosas para o
combate ofensivamente e defensivamente respectivamente.
Poções e comida possuem um caráter mais de modificador de pontos de vida do
PC. Possuem um evento associado ao uso deles. Apesar de serem principalmente para
modificar os pontos de vida do PC, nada impede que possa existir uma poção mágica
cujo evento seja fazer o PC perder a arma.
35
5.
Regras de conduta
O objetivo de haver regras de conduta é impedir que jogadores façam atitudes
que não agradam aos outros jogadores, e que caso desobedecidas possam levar ao
jogador ser banido do jogo.
Algumas regras que são indispensáveis que os jogadores as sigam seriam
Não ser permitido a discriminação de jogadores (como raça e
religião);
Não ser permitido o assassinato em massa de jogadores sem
motivo;
Não ser permitido um jogador bloquear ou prender outro
jogador.
Com isso, o jogo se torna agradável e divertido.
3.6.7. Estratégias de jogo
1. Tráfego de informações entre cliente / servidor
Quando um jogador faz uma ação, nem todos os outros precisam saber disso.
Mandar todas as informações para todos os clientes não é interessante, pois vai
sobrecarregar a rede de informação que possivelmente será inútil para muitos jogadores.
Para evitar esse problema foi pensado em duas soluções:
a) pode haver uma espécie de barreira que impossibilite o jogador de enxergar
qualquer acontecimento que ocorra além de uma distância determinada (sua área de
visualização). Assim, um jogador A não receberia a informação que um jogador C
está realizando uma ação, pois esse jogador está fora da área de visualização. Caso um
jogador B faça uma ação dentro da área de A , este último receberá as informações
do servidor.A figura abaixo exemplifica essa situação. A área branca é o campo de
visualização do jogador A , e este apenas recebe informações de eventos que ocorrem
dentro dessa área.
36
Figura 3
Eventos que ocorrem fora do campo de visão dos jogadores não são
processados por esses.
O problema dessa a solução é que ela acaba com o fluxo de dados inúteis na
rede, mas aumenta drasticamente o processamento do servidor, pois ele terá que
processar para cada ação os jogadores que serão informados dessa ação, chegando a ser
totalmente inviável para muitos clientes.
b) O envio de informação passa a ser baseado em territórios. A informação é
enviada a todos os jogadores que estão naquela região. Com essa solução pode-se
dividir o gerenciamento de cada território para computadores diferentes. Assim ainda
ocorre envio de informação inútil, mas em uma escala bem menor sem gasto de
processamento. Exemplificando, o jogador A não recebe informações de ações do
37
jogador C (e vice-versa), pois eles estão em territórios diferentes. Porém, tudo o que o
jogador B fizer será passado para o jogador A .
Figura 4
Eventos ocorridos fora do território atual de cada jogador não são
recebidos por esses.
O problema dessa solução é que pode ocorrer um superpovoamento em um
território e com isso sobrecarregar a rede do mesmo jeito.Território
Apesar de também ter um ponto negativo, a solução b tem uma vantagem: caso
os territórios estejam divididos entre vários computadores, a lentidão no funcionamento
de um dos computadores atinge apenas o(s) território(s) que ele gerencia, enquanto os
outros territórios do jogo continuam funcionando normalmente.
Foi implementada a idéia da solução dois, enquanto a solução um foi inserida no
cliente para informar ao jogador apenas as ações úteis a ele.
38
2.
Se um dos jogadores possui alto tempo de lag (latência), isso não
pode interferir no funcionamento do jogo e do servidor.
A solução é cada jogador possui uma thread específica no servidor para tratar
suas comunicações e interações com o mundo , assim caso um jogador esteja com lag,
os outros jogadores continuarão podendo se comunicar com o servidor e/ou extrair
informações do mesmo.
3.
Integridade do mundo
O mundo em que estará acontecendo o jogo está sendo executado no servidor,
e cada jogador possui uma pequena visão deste mundo. Quando um jogador realiza uma
ação, ela só é válida quando o servidor retorna uma mensagem para o jogador com a
confirmação de sua ação. Dessa forma, caso um jogador esteja com lag alto e possua
uma visão atrasada do mundo (por exemplo, com um espaço para movimentação
enquanto na realidade não possua espaço, pois está sendo bloqueado por outro jogador)
o servidor não permite a movimentação, já que o jogador está bloqueado. O mundo
estará integro no servidor, e nos jogadores a integridade do mundo visto dependerá do
tempo de transmissão de dados pela rede.
Quanto menor o tempo de transmissão da informação pela rede, maior a
visualização da integridade do mundo pelos jogadores e a fluidez do jogo.
Jogadores com alto lag terão uma resposta de movimentação mais demorada e
de forma travada, observando outros jogadores se movimentarem de forma espaçada.
Analogamente, jogadores com boas taxas de transferência de dados observarão os
jogadores com lag se movimentarem de forma mais travada e com respostas lentas.
39
4.
Mudança de um personagem de um território para outro
O jogador pode passar de um território do mundo para outro através de portais.
Os portais são áreas do mapa especiais que possuem como objetivo serem os pontos de
transporte do personagem do jogador para outros territórios. Muitos objetos podem
atuar como portais:
Portas;
Pontes;
Buracos;
Escadas;
Pontos de teletransporte;
Cada portal possui um ponto de entrada e um ponto de saída, para permitir o
transporte entre esses pontos. Os portais também possuem a informação de qual
servidor está gerenciando o território destino. O personagem, ao passar pelo portal, é
retirado do grupo de personagens do território em que estava e inserido no grupo de
personagens do território destino.
Exemplificando, um personagem que está na cidade Zihr passa sobre uma área
que é uma escada para um nível abaixo. Na verdade essa área é um portal para o
território Esgotos de Zihr , assim o personagem é transportado para o mapa dos
esgotos da cidade no término da escada (local definido como saída do portal).
3.6.8. Testes
Foram feitos testes de duas maneiras diferentes: em modo local, com um
programa servidor e vários programas clientes sendo executados na mesma máquina,
como processos distintos, e em rede, onde executamos o servidor em um computador, e
outros computadores se conectaram ao servidor através da Internet.
Como esperado, o teste na máquina local procedeu de forma suave e rápida, sem
nenhum inconveniente. Isso nos fez perceber que um servidor pode ser executado na
mesma máquina de um cliente, para o caso de jogos sem muitos computadores
disponíveis.
40
O teste envolvendo a rede foi um pouco mais complicado, pois tivemos que lidar
com situações adversas como quedas de conexão e latência. Em geral o sistema se
comportou bem, e os tempos de resposta entre computadores conectados através de
acesso discado (56kbps) foram satisfatórios.
Informações sobre teste de desempenho de sistemas leia [10].
3.7. Dificuldades encontradas
Desde o início do projeto encontramos dificuldades nas mais diversas áreas. A
idéia inicial de fazer com que servidores e clientes se comunicassem através de MPI ou
outros métodos de computação distribuída foi aos poucos sendo descartadas, pois não
encontramos um protocolo de comunicação com dinamismo suficiente para cumprir os
requisitos de comunicação desejados.
Outra dificuldade foi à obtenção de bibliografia específica de jogos e suas
estratégias, assunto raramente abordado por profissionais e acadêmicos em suas
publicações.
41
4. Conclusão e Trabalhos Futuros
Podemos perceber que um projeto dessa natureza não é simples ou rápido de ser
feito. Existem muitas facetas envolvidas, e todas requerem um alto grau de empenho,
pesquisa e desenvolvimento. Não é à toa que o mercado de jogos seja tão escasso no
Brasil, onde reina a pirataria e falta de leis voltadas ao software. Grande investimento
deve ser feito para tornar um trabalho acadêmico em uma fonte rentável
comercialmente, e as chances de retorno são baixas.
Mesmo assim, os resultados do projeto efetuado foram satisfatórios, e com um
pouco de disponibilidade extra pode fazer com que o trabalho fosse levado adiante,
aumentando os recursos e o apelo comercial do jogo. A idéia é que o projeto seja
continuado por outras equipes, tanto no ramo da tecnologia (para o desenvolvimento de
novos recursos) quanto para times de desenvolvimento de jogos (elaboração e
manutenção de mundos, regras, personagens, cenários, etc).
Devido à profundidade ilimitada que podemos adicionar ao projeto, são também
inúmeros os trabalhos que podem ser desenvolvidos a partir do mesmo. Teoricamente
tudo pode ser incrementado, como por exemplo:
Uso de clusters para aumentar a disponibilidade do servidor;
Melhoria da interface gráfica de todos os programas
envolvidos (cliente, servidor, website);
Utilização de uma nova abordagem gráfica para facilitar a
interação do jogador com o mundo virtual. Por exemplo,
utilizar interfaces em 3 dimensões com câmera livre,
expandindo o grau de exploração do jogador;
Implementação de um sistema de Inteligência Artificial para o
controle de NPCs, eventos periódicos e elementos de batalha;
Melhoria do sistema de MOORPG em si: adição de magias,
classes, regras, mundos, raças, intrigas e histórias;
Adição de trilha sonora e efeitos especiais;
Possibilidade de criação de cidades ou vilas, para que os
personagens possam ter seu próprio estabelecimento nos
mundos virtuais;
42
Glossário
BBS
Acrônimo de Bulletin Board System (sistema de quadro de recados). É um centro
de mensagens eletrônicas, a maioria com um interesse específico. Eles permitem
que o usuário deixe uma mensagem ou responda mensagens deixadas por outros,
como um fórum de mensagens.
Cliente
Parte cliente da arquitetura cliente-servidor. Tipicamente, o cliente é a aplicação
que roda em um computador pessoal ou numa estação de trabalho e confia ao
servidor o processo de algumas operações.
Client Side
Códigos executados diretamente no cliente. Assim o cliente tem acesso ao código
fonte, e seu computador tem que estar habilitado a executar esse tipo de código.
Cyberespaço
Termo criado por William Gibson em seu livro Neuromancer (1984), é uma
metáfora para descrever o espaço não físico criado por sistemas de computadores.
Como no espaço físico, cyberespaços possuem objetos e diferentes modos de
interação. Alguns programas, como os jogos de computador, são desenvolvidos
para criar cyberespaços especias, que se assemelham ao mundo real am algumas
partes.
DoS
Denial of Service. Tipo de ataque a servidores baseado em sobrecarga de
informações. Usualmente é realizado com o sincronismo de milhares de estações
requerendo informações de um mesmo servidor. Esse servidor não consegue
processar todos os pedidos e acaba negando todos.
FAQ
Acrônimo de Frequent Answered Questions, perguntas freqüentemente feitas.
Usualmente é tratado como um texto com perguntas e respostas comuns.
MMORPG
Acrônimo de Massive Multiplayer Online Role Playing Game, é basicamente um
jogo eletrônico onde um número muito grande de pessoas podem interagir de
maneira simultânea pela Internet, e com os mesmos conceitos do RPG.
43
MUD
Multi User Dimension (Dimensão Multi Usuário) ou Multi User Dungeon
(Calabouço Multi Usuário) é um cyberespaço onde os usuários tomam identidade
através de avatares e podem interagir entre si. Originalmente designam jogos de
aventuras com castelos antigos, criaturas fantásticas e itens mágicos. Atualmente
o termo é usado mais genericamnete para se referir a qualquer cyberespaço.
Patch
Atualizações de um programa, correção de falhas e novas funcionalidades.
PBEM
Play By Eletronic Mail é um tipo de jogo onde os jogadores usam o e-mail para se
comunicar. Pode ser feito por moderadores humanos ou por listas de e-mail
automáticas.
RPG
Acrônimo de Role-Playing Games (jogo de interpretação de papéis). Jogar RPG é
semelhante a ler uma história, assistir a um filme e participar de um jogo, tudo ao
mesmo tempo[8].
Server Side
Trecho de código compilado / interpretado no lado servidor de uma conexão
cliente servidor. Geralmente é usado em linguagens dinâmicas de Internet. O
output desse processo é texto simples em uma linguagem de marcação como
HTML.
Servidor
Computador ou dispositivo de rede que gerencia os recursos da rede.
Skin
Alterações de interface de um software, mudando suas cores e formas.
SQL
Structured Query Language, linguagem popularmente usada para consulta e
acesso a bancos de dados.
Website
Conjunto de páginas com hipermídia disponíveis em um servidor, permitindo
acesso de qualquer usuário da Internet.
44
Referências
[1] ALBUQUERQUE, Fernando. TCP/IP Internet: Programação de Sistemas
Distribuídos. Axcel Books, 2001.
[2] AXFORD, Tom. Concurrent Programming: Fundamental Techniques for Real-Time
and Parallel Software Design. John Wiley & Sons, 1990.
[3] BARBACCI, Mario; Klein, Mark H.; Longstaff, Thomas H. & Weinstock, Charles
B. Quality Attributes (CMU/SEI-95-TR-021). Pittsburgh, PA: Software Engineering
Institute, Carnegie Mellon University, 1995.
[4] BETHKE, Erik. Game Development and Production. Wordware Publishing, 2003.
[5] BETTOCCHI, Eliane. Role-playing Game: um jogo de representação visual de
gênero. Dissertação de Mestrado em Design, Pontifícia Universidade Católica do Rio de
Janeiro, 2002.
[6] BRACKEEN, David. Developing Games in Java. New Riders, 2003.
[7] DANTAS, Mario. Tecnologia de Redes de Comunicação e Computadores. Axcel
Books, 2002.
[8] DENNING, Troy; Brown, Timothy B. Dungeons & Dragons: Livro do Mestre.
Grow, 1994.
[9] FRIEDL, Jeffrey E. F. Mastering Regular Expressions. O Reilly & Associates,
2002.
[10] JAIN, R. K. The Art of Computer Computer Systems Performance Analysis:
Techniques for Experimental Design, Measurement, Simulation, and Modeling. John
Wiley & Sons, 1991.
[11] PRESSMAN, Roger S. Engenharia de Software. Mc Graw Hill, 2002.
[12] STEVENS, Richard et al. Unix Network Programming, Vol. 1: The Sockets
Networking API. Addison-Wesley Pub Co, 2003.
[13] TANENBAUM, Andrew S. Redes de Computadores. Campus, 2003.
[14] TANEMBAUM, Andrew S.; Steen, van Maarten. Distributed Systems: Principles
and Paradigms. Prentice Hall, 2002.
[15] TORRES, Gabriel. Redes de Computadores: Curso Completo. Axcel Books, 2001.
45
Anexos
// classe do pacote de mensagens
package mensagens;
import java.io.Serializable;
// mensagem Padrão
public class Mensagem implements Serializable{
/* o atributo ação informa o tipo de ação e/ou informação que
a mensagem carrega */
protected int acao;
/* atributo identificador do jogador */
protected int jogadorID;
/* prioridade da mensagem */
protected int prioridade;
/* conjunto de parâmetros que são levados pela mensagem,
seu uso, bem como a quantidade de parâmetros e seus
respectivos significados são determinados pela ação
que a mensagem informa*/
protected int[] parametros;
/* construtor de mensagens que utilizam
os parâmetros */
public Mensagem(int acao, int jogadorID, int prioridade, int[]
parametros) {
this.acao = acao;
this.jogadorID = jogadorID;
this.prioridade = prioridade;
this.parametros = parametros;
}
/* construtor de mensagens que não
utilizam parâmetros */
public Mensagem(int acao, int jogadorID, int prioridade) {
this.acao = acao;
this.jogadorID = jogadorID;
this.prioridade = prioridade;
this.parametros = new int[0];
}
/* métodos para busca de informação */
public int retAcao(){
return this.acao;
}
public int retJogadorID(){
return this.jogadorID;
}
public int retPrioridade(){
return this.prioridade;
}
46
public int[] retParametros(){
return this.parametros;
}
}
// classe do pacote de mensagens
package mensagens;
// Mensagem com strings
public class MensagemString extends Mensagem{
/* Atributo que é a mensagem string levada */
protected String string;
/* Construtor da classe, é ignorado os
parâmetros herdados da classe mensagem */
public MensagemString(int acao, int id, int prioridade, String
string){
super(acao,id,prioridade);
this.string = string;
}
/* método de busca de informação */
public String retString(){
return string;
}
}
// classe do pacote de mensagens
package mensagens;
import utils.Tipos;
import mapa.Mapa;
/* Mensagem que que informa Mapa do jogo,
mensagem tipiciamente
servidor -> cliente */
public class MensagemMapa extends Mensagem{
/* Atributo com o mapa que será informado */
protected Mapa mapa;
/* construtor, mensagem especípica para a ação
de enviar mapa */
public MensagemMapa(int id, int prioridade, Mapa mapa){
super(Tipos.ACAO_ENVIO_MAPA,id,prioridade);
this.mapa = mapa;
}
/* método de busca de informação */
public Mapa retMapa(){
return this.mapa;
}
}
47
package eventos;
import beings.Being;
interface Evento {
public String eventoSobre(Being ser);
}
package eventos;
import beings;
class EventoCura implements Evento{
private int cura;
public EventoCura(int cura){
this.cura = cura;
}
public void setcura(int cura){
this.cura = cura;
}
public String eventoSobre(Being ser){
ser.recebaCura(this.cura);
return "Você foi curado em "+this.cura+" pontos de vida";
}
}
package eventos;
import beings;
class EventoVeneno implements Evento{
private int dano;
public EventoVeneno(int dano){
this.dano = dano;
}
public void setDano(int dano){
this.dano = dano;
}
public String eventoSobre(Being ser){
ser.recebaDano(this.dano);
return "Você recebeu "+this.dano+" pontos de Dano por
envenenamento";
}
}
package eventos;
import beings.Player;
48
import beings.Being;
class EventoAtaque extends Thread implements Evento{
private Player atacante;
private Player defensor;
private boolean noMercy;
public EventoAtaque(Player atacante){
this.atacante = atacante;
noMercy = true;
}
public String eventoSobre(Being def){
this.defensor = (Player)def;
this.start();
return "Você está sendo atacado por "+ atacante.getNome()
+"!";
}
public void run(){
while(defensor.estahVivo() && noMercy){
this.defensor.recebaAtaque(atacante.ataque());
try{
sleep(1000);
}catch(InterruptedException ex){}
}
}
public void pareAtaque(){
noMercy = false;
}
}
49
package mapa;
import java.io.Serializable;
public class Mapa implements Serializable{
private PosicaoMapa[][] mapa;
private int largura;
private int altura;
public Mapa(PosicaoMapa[][] mapa){
this.mapa = mapa;
altura = mapa.length;
largura = mapa[0].length;
}
public void setPosMapa(int x, int y, PosicaoMapa valor){
if(x<altura && y<largura)
this.mapa[x][y] = valor;
}
public int retLargura(){
return this.largura;
}
public int retAltura(){
return this.altura;
}
public Mapa subMapa(int x0, int y0, int tamX, int tamY){
PosicaoMapa[][] submapa = new PosicaoMapa[tamX][tamY];
for(int i=0; i<tamX; i++)
for(int j=0; j<tamY; j++){
int posX = x0 + i;
if(posX>=0 && posX<retAltura()){
int posY = y0 + j;
if(posY>=0 && posY<retLargura()){
submapa[i][j] = mapa[posX][posY];
}else{
submapa[i][j] = new
PosicaoMapa(2,true);
}
}else{
submapa[i][j] = new PosicaoMapa(2,true);
}
}
return new Mapa(submapa);
}
public int getFiguraPosMapa(int x, int y){
return mapa[x][y].getFigura();
}
public boolean bloqueado(int x, int y){
if(x>=0 && x<retAltura())
if(y>=0 && y<retLargura())
return mapa[x][y].bloqueado();
return true;
}
50
public boolean terrenoBloqueado(int x, int y){
if(x>=0 && x<retAltura())
if(y>=0 && y<retLargura())
return mapa[x][y].terrenoBloqueado();
return true;
}
}
package mapa;
import java.util.Vector;
import java.io.Serializable;
public class PosicaoMapa implements Serializable{
private int figura;
private Vector objetos;
private boolean bloqueante;
public PosicaoMapa(int figura, boolean block){
this.objetos = new Vector();
this.figura = figura;
this.bloqueante = block;
}
public boolean bloqueado(){
if(!bloqueante){
for(int i=0; i<objetos.size(); i++){
if(((PosicaoMapa)objetos.get(i)).bloqueado())
return true;
}
}
return bloqueante;
}
public boolean terrenoBloqueado(){
return this.bloqueante;
}
public void adicioneObjeto(ObjetoMapa objeto){
objetos.add(objeto);
}
public void removaObjeto(String id){
for(int i=0; i<objetos.size(); i++){
if(((ObjetoMapa)objetos.get(i)).getId() == id)
objetos.remove(i);
}
}
public int getFigura(){
return this.figura;
}
}
51
package mapa;
public class ObjetoMapa extends PosicaoMapa{
/* Identificador do objeto */
private String id;
public ObjetoMapa(int figura, boolean block, String id){
super(figura, block);
this.id = id;
}
public String getId(){
return this.id;
}
}
52
package gerenciadores;
import java.util.Vector;
import servidor.JogadorServidor;
public class GerenciadorJogadores {
private static GerenciadorJogadores gerenciador;
private Vector jogadores;
private int counter;
static public GerenciadorJogadores retGerenciador(){
if(gerenciador == null){
gerenciador = new GerenciadorJogadores();
}
return gerenciador;
}
private GerenciadorJogadores() {
jogadores = new Vector();
counter = 0;
}
synchronized public int insiraJogador(JogadorServidor jogador){
jogadores.add(jogador);
return counter++;
}
synchronized public void informeMovimento(int jogadorID, int lado){
for(int i=0;i<jogadores.size();i++){
((JogadorServidor)jogadores.get(i)).informeMovimento(jogadorID,
lado);
}
}
synchronized public void informeFala(int jogadorID, String fala){
for(int i=0;i<jogadores.size();i++){
((JogadorServidor)jogadores.get(i)).informeFala(jogadorID,
fala);
}
}
synchronized public void informeNovoJogador(JogadorServidor
jogador){
for(int i=0;i<jogadores.size();i++){
((JogadorServidor)jogadores.get(i)).conhecaNovoJogador(jogador);
}
}
synchronized public void removaJogador(JogadorServidor jogador){
this.jogadores.remove(jogador);
}
synchronized public JogadorServidor retJogador(int jogadorID){
for(int i=0;i<jogadores.size();i++){
if(((JogadorServidor)jogadores.get(i)).retJogadorID() ==
jogadorID){
return ((JogadorServidor)jogadores.get(i));
}
}
53
return null;
}
public Vector retJogadores(){
return jogadores;
}
}
54
package gerenciadores;
import mapa.*;
public class GerenciadorMapa {
private static GerenciadorMapa gm;
private Mapa mapa;
private GerenciadorMapa(){
// mapa pra teste
PosicaoMapa[][] m = new PosicaoMapa[100][100];
boolean tp = false;
for(int i=0;i<100;i++){
tp = !tp;
for(int j=0;j<100;j++){
if(tp)
m[i][j] = new PosicaoMapa(1, false);
else
m[i][j] = new PosicaoMapa(2, false);
tp = !tp;
}
}
mapa = new Mapa(m);
}
static public GerenciadorMapa retGerenciador(){
if(gm == null)
gm = new GerenciadorMapa();
return gm;
}
public Mapa retMapa(){
return mapa;
}
public int retAltura(){
return mapa.retAltura();
}
public int retLargura(){
return mapa.retLargura();
}
public Mapa getMapa(int x0, int y0, int tamX, int tamY){
return mapa.subMapa(x0,y0,tamX,tamY);
}
public boolean bloqueado(int x, int y){
return mapa.bloqueado(x,y);
}
}
55
//pacote de seres do mundo
package beings;
import itens.Item;
/*
classe abstrata que define os
atributos principais que os seres
que habitam o MUD possuem
*/
public abstract class Being{
protected
protected
protected
protected
protected
protected
protected
protected
protected
int hp;
int hpMax;
int exp;
int forca;
String nome;
int imagem;
Item[] itens;
int quantItens;
int pesoSuportado;
public abstract int recebaDano(int ataqueAdversario);
public abstract int ataque();
public abstract int defesa();
public boolean estahVivo(){
return hp > 0;
}
public String getNome(){
return this.nome;
}
public int getImagem(){
return this.imagem;
}
public Item[] getItens(Integer qntItens){
qntItens = new Integer(quantItens);
return itens;
}
public Item getItem(int index){
try{
if(index < quantItens)
return itens[index];
else
return null;
}catch(NullPointerException ex){return null;}
}
public boolean suportaPesoAdicional(int peso){
for(int i=0; i<quantItens; i++){
if(itens[i] != null)
peso = peso + itens[i].getPeso();
}
return peso <= this.pesoSuportado;
}
}
56
import itens.*;
import utils.TabelaForca;
import utils.TabelaExperiencia;
public class Player extends Being{
private
private
private
private
Armadura armadura;
Arma arma;
int danosCausados;
int level;
public Player(String nome, int level, int hp, int hpMax, int
exp, int forca, int danosCausados, int imagem){
this.nome = nome;
this.level = level;
this.hp = hp;
this.hpMax = this.hpMax;
this.exp = exp;
this.forca = forca;
this.danosCausados = danosCausados;
this.imagem = imagem;
}
public boolean estahVivo(){
return this.hp > 0;
}
public int recebaAtaque(int ataqueAdversario){
int dano = ataqueAdversario - this.defesa();
this.hp = this.hp - dano;
return dano;
}
public int defesa(){
return this.armadura.getDefesa();
}
public int ataque(){
return this.forca + this.arma.getAtaque();
}
public void recebaInfoDano(int danoCausado){
this.danosCausados = this.danosCausados + danoCausado;
}
public int subiuNivelAtaque(){
if(TabelaForca.tabela[this.forca-10] <= danosCausados){
this.forca++;
return this.forca;
}
return -1;
}
public int recebaDano(int dano){
this.hp = this.hp - dano;
this.hp = this.hp < 0 ? 0 : this.hp;
return this.hp;
}
public int subiuNivel(){
57
if(TabelaExperiencia.tabela[this.level] <= this.exp){
this.level++;
this.hpMax = this.hpMax + 5;
this.pesoSuportado = this.pesoSuportado + 50;
return this.level;
}
return -1;
}
public String getNomeArma(){
return this.arma.getNome();
}
public String getNomeArmadura(){
return this.armadura.getNome();
}
public String getNome(){
return this.nome;
}
public int getImagem(){
return this.imagem;
}
}
58
// pacote itens
package itens;
public class Item {
private int peso;
private String nome;
private int preco;
public Item(String nome, int peso, int preco){
this.peso = peso;
this.nome = nome;
this.preco = preco;
}
public String getNome(){
return this.nome;
}
public int getPeso(){
return this.peso;
}
public int getPreco(){
return this.preco;
}
public void setPeso(int peso){
this.peso = peso;
}
public void setNome(String nome){
this.nome = nome;
}
public void setPreco(int preco){
this.preco = preco;
}
}
// pacote itens
package itens;
public class Armadura extends Item{
private int valorDefesa;
public Armadura(String nome, int peso, int preco, int
valorDefesa){
super(nome, peso, preco);
this.valorDefesa = valorDefesa;
}
public int getDefesa(){
return this.valorDefesa;
}
}
59
// pacote itens
package itens;
public class Arma extends Item{
private int valorAtaque;
public Arma(String nome, int peso, int preco, int valorAtaque){
super(nome, peso, preco);
this.valorAtaque = valorAtaque;
}
public int getAtaque(){
return this.valorAtaque;
}
}
60
package servidor;
import
import
import
import
import
import
import
java.net.ServerSocket;
java.nio.channels.ServerSocketChannel;
java.net.InetSocketAddress;
java.net.Socket;
java.io.Serializable;
java.io.ObjectInputStream;
java.io.ObjectOutputStream;
public class Servidor {
public Servidor() {
try{
ServerSocketChannel serversockch = ServerSocketChannel.open();
serversockch.socket().bind(new InetSocketAddress(10101), 100);
// Aguardando jogadores ...
while(true){
System.out.println("Esperando Jogadores!!!");
Socket socket = serversockch.accept().socket();
System.out.println("Entrou um jogador!");
JogadorServidor jogador = new JogadorServidor(socket);
jogador.start();
}
}catch(Exception ex){
System.err.println("Erro no servidor: "+ex.toString());
}
}
}
import
import
import
import
java.io.ObjectInputStream;
java.io.ObjectOutputStream;
java.net.Socket;
java.io.IOException;
import
import
import
import
import
utils.Tipos;
beings.Player;
mensagens.*;
gerenciadores.*;
mapa.Mapa;
public class JogadorServidor extends Thread{
private
private
private
private
private
private
private
private
Socket socket;
int jogadorID;
ObjectInputStream in;
ObjectOutputStream out;
String username;
Player player;
int posicaoX;
int posicaoY;
public JogadorServidor(Socket socket) {
this.socket = socket;
try{
61
this.out = new
ObjectOutputStream(this.socket.getOutputStream());
this.in = new ObjectInputStream(this.socket.getInputStream());
jogadorID =
(GerenciadorJogadores.retGerenciador()).insiraJogador(this);
posicaoX = 50;
posicaoY = 50;
int[] posicao = new int[2];
posicao[0] = posicaoX;
posicao[1] = posicaoY;
this.out.writeObject(new Mensagem(Tipos.ACAO_CONFIRMAR,
this.jogadorID, 9, posicao));
this.out.flush();
username = ((MensagemString)this.in.readObject()).retString();
// player = getPlayerOfUser(userName);
}catch(Exception ex){ ex.printStackTrace();
System.out.println("Erro jogador Servidor!");
GerenciadorJogadores.retGerenciador().removaJogador(this);}
}
public void run(){
GerenciadorJogadores.retGerenciador().informeNovoJogador(this);
try{
System.out.println("Entrou no while");
while(true){
Mensagem mens = new Mensagem(-1,-1,-1);
try{
mens = (Mensagem)this.in.readObject();
}catch(ClassCastException expt){continue;}
catch(ClassNotFoundException expt2){continue;}
switch(mens.retAcao()){
case Tipos.ACAO_MOVER:
if(mens.retParametros()[0] ==
Tipos.ACAO_MOVER_CIMA){
if(!GerenciadorMapa.retGerenciador().bloqueado(posicaoX, posicaoY 1)){
posicaoY = posicaoY - 1;
GerenciadorJogadores.retGerenciador().informeMovimento(this.jogadorID,
mens.retParametros()[0]);
}
}else if (mens.retParametros()[0] ==
Tipos.ACAO_MOVER_DIREITA){
if(!GerenciadorMapa.retGerenciador().bloqueado(posicaoX + 1,
posicaoY)){
posicaoX = posicaoX + 1;
GerenciadorJogadores.retGerenciador().informeMovimento(this.jogadorID,
mens.retParametros()[0]);
}
}else if (mens.retParametros()[0] ==
Tipos.ACAO_MOVER_BAIXO){
if(!GerenciadorMapa.retGerenciador().bloqueado(posicaoX, posicaoY +
1)){
posicaoY = posicaoY + 1;
62
GerenciadorJogadores.retGerenciador().informeMovimento(this.jogadorID,
mens.retParametros()[0]);
}
}else if (mens.retParametros()[0] ==
Tipos.ACAO_MOVER_ESQUERDA){
if(!GerenciadorMapa.retGerenciador().bloqueado(posicaoX - 1,
posicaoY)){
posicaoX = posicaoX - 1;
GerenciadorJogadores.retGerenciador().informeMovimento(this.jogadorID,
mens.retParametros()[0]);
}
}
break;
case Tipos.ACAO_FALA:
GerenciadorJogadores.retGerenciador().informeFala(this.jogadorID,
username + ": "+((MensagemString)mens).retString());
break;
case Tipos.ACAO_REQUISITAR_MAPA:
Mapa map =
GerenciadorMapa.retGerenciador().getMapa(posicaoX-8, posicaoY-5
,16,10);
this.out.writeObject(new
MensagemMapa(this.jogadorID, 1, map));
this.out.flush();
break;
}
}
}catch(IOException ex){ex.printStackTrace();
System.out.println("Erro jogador Servidor!");
GerenciadorJogadores.retGerenciador().removaJogador(this);}
}
public void informeMovimento(int IDandante, int lado){
try{
int[] param = new int[1];
param[0] = lado;
this.out.writeObject(new Mensagem(Tipos.ACAO_MOVER, IDandante,
1, param));
this.out.flush();
}catch(IOException ex){System.out.println("Erro informar
movimento!");}
}
public void informeFala(int IDfalante, String fala){
try{
this.out.writeObject(new MensagemString(Tipos.ACAO_FALA,
IDfalante, 3, fala));
this.out.flush();
}catch(IOException ex){System.out.println("Erro informar fala!");}
}
public int retJogadorID(){
return jogadorID;
}
public String retUsername(){
63
return this.username;
}
public void conhecaNovoJogador(JogadorServidor novoJog){
try{
this.out.writeObject(new
MensagemString(Tipos.ACAO_NOVO_JOGADOR, novoJog.retJogadorID(),2,
novoJog.retUsername()));
this.out.flush();
}catch(IOException ex){System.out.println("Erro informar novo
Jogador");}
}
}
64
// pacote cliente
package cliente;
/* Classes importadas, classes de IO */
import java.nio.channels.SocketChannel;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
/* Classes importadas */
import mensagens.*;
import utils.Tipos;
import mapa.Mapa;
public class Jogador {
private
private
private
private
private
private
private
int id;
ObjectInputStream in;
ObjectOutputStream out;
String nome;
int posX;
int posY;
Mapa mapa;
/* Classe para interações entre o Usuário
e o MUD */
/* Construtor
conecta com o servidor cujo ip é address
*/
public Jogador(String address) {
try{
// abre uma conexão
SocketChannel socketch = SocketChannel.open(new
InetSocketAddress(address, 10101));
Socket socket = socketch.socket();
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
// recebe uma mensagem de confirmação do servidor
Mensagem mens = ( (Mensagem) this.in.readObject());
// retira o identificador do jogador
id = mens.retJogadorID();
// retira a posição espacial
// do personagem no mapa
posX = mens.retParametros()[0];
posY = mens.retParametros()[1];
OuvinteJogador ouvinte = new OuvinteJogador(this.in, this);
ouvinte.start();
}catch(Exception ex){System.err.println(ex.toString());}
}
// seta/muda o nome do personagem
public void setNome(String nome){
this.nome = nome;
try{
this.out.writeObject(new MensagemString(Tipos.ACAO_SETAR_NOME,
this.id, 2, this.nome));
65
this.out.flush();
}catch(IOException ex){System.err.println("Falha ao setar o
nome");}
}
/*
método para requisitar o mapa da região em que
o personagem está
*/
public void getMapa(){
try{
this.out.writeObject(new Mensagem(Tipos.ACAO_REQUISITAR_MAPA,
this.id, 1));
this.out.flush();
}catch(IOException ex){System.err.println("Falha ao requisitar
mapa");}
}
/*
método para informar ao server o desejo de se movimentar
no mapa
*/
public void movimente(int lado){
int[] param = new int[1];
param[0] = lado;
try{
this.out.writeObject(new Mensagem(Tipos.ACAO_MOVER, this.id, 1,
param));
this.out.flush();
}catch(IOException ex){System.err.println(ex.toString());}
}
/*
setar o mapa
*/
public void setMapa(Mapa map){
this.mapa = map;
}
/*
informar o servidor da fala
*/
public void fale(String fala){
try{
this.out.writeObject(new MensagemString(Tipos.ACAO_FALA,
this.id, 1, fala));
this.out.flush();
}catch(IOException ex){System.err.println(ex.toString());}
}
}
66
// pacote cliente
package cliente;
import java.io.ObjectInputStream;
import java.io.IOException;
import mensagens.*;
import utils.Tipos;
import mapa.Mapa;
/*
Classe que serve como
handler para receber mensagens do
servidor
*/
public class OuvinteJogador extends Thread{
private ObjectInputStream in;
private Jogador jogador;
public OuvinteJogador(ObjectInputStream in, Jogador jogador){
this.in = in;
this.jogador = jogador;
}
/*
método que define as funções
que a thread fará
*/
public void run(){
while(true){
Mensagem mens = new Mensagem(-1,-1,-1);
try{
mens = (Mensagem) in.readObject();
}catch(Exception ex){break;}
switch(mens.retAcao()){
case Tipos.ACAO_MOVER: jogador.getMapa();break;
case Tipos.ACAO_FALA:
Client.retCliente().escrevaTexto(((MensagemString)mens).retString());b
reak;
case Tipos.ACAO_ENVIO_MAPA:
jogador.setMapa(((MensagemMapa)mens).retMapa());
Client.retCliente().desenharMapa(((MensagemMapa)mens).retMapa());
}
}
}
}