Esse artigo faz parte da revista WebMobile edição 2. Clique aqui para ler todos os artigos desta edição

wm2_capa.gif

Clique aqui para ler este artigo em PDFimagem_pdf.jpg despercebido, como uma péssima jogabilidade, fazendo-o alcançar algum sucesso. Há jogos baseados em SMS com interface gráfica bastante pobres que estão entre os mais vendidos pelas operadoras de telefonia celular (apesar do fato de que cada SMS custasse 14 centavos na época).

Para mostrar alguns conceitos de interatividade que podem dar outra cara para seu aplicativo, usaremos o jogo Mobile Invaders, desenvolvido pelos nossos colegas Renato Iida e Eduardo Peixoto publicado na primeira edição da WebMobile. Foram introduzidas algumas modificações no jogo original a fim de demonstrar o funcionamento das tecnologias Record Management System e Generic Connection Framework em jogos para celulares, além de tornar o jogo mais atrativo aos seus usuários. As modificações são as seguintes: foram introduzidas fases com nível de dificuldade crescente, pontuação, armazenamento local de pontos e o mais interessante, armazenamento de pontos em um servidor. Tudo isto utilizando a tecnologia Java (J2ME/MIDP e J2EE).

Nesse artigo, você irá aprender a usar as tecnologias Java necessárias para colocar em prática parte dessas idéias. Será utilizado o Record Management System (RMS) para persistência de dados. As classes para comunicação via Internet e os Servlets para a implementação do servidor serão apresentados no próximo artigo da série.

O que mudou no Mobile Invaders?

Da forma como foi concebido, o Mobile Invaders teve como objetivo a introdução de várias técnicas e arquiteturas indispensáveis para o desenvolvimento de jogos. Para adequá-lo às tecnologias que queremos apresentar neste artigo, tornou-se necessária à criação de novas funcionalidades. Para tanto, modificamos algumas partes do código, criamos algumas classes e acrescentamos algumas telas de menu.

É hora de entender como o jogo ficou estruturado, quais foram as principais modificações e as novas regras.

As regras

As regras do jogo se mantiveram as mesmas. Há uma nave controlada pelo jogador que tem como objetivo destruir todos os inimigos da tela. A quantidade de inimigos, sua velocidade e quantidade de tiros simultâneos aumentam à medida que o jogador passa para uma nova fase. Para que o jogo não fique muito injusto, a quantidade de tiros da nave também aumenta, mas não sua velocidade (pois tornaria o jogo fácil demais). Os parâmetros que definem a dificuldade do jogo são facilmente editáveis e você pode alterá-los para tornar uma partida mais difícil caso ache que precise de um pouco mais de emoção. Altere-os e peça para que seus amigos joguem até que você perceba que o jogo atingiu um nível de dificuldade razoável.

Para a alegria de uns e tristeza de outros, esse jogo não tem uma quantidade limite de fases. Isso mesmo, ele se enquadra na categoria dos jogos do bom e velho Atari. É claro que com um pouco mais de interatividade. Esse recurso é interessante, pois tende a aumentar o ciclo de vida do jogo, fazendo com que os jogadores continuem jogando para manter seu recorde, visto que não há limite para o número de pontos. De fato, o número máximo de pontos é dado por uma variável do tipo int, de 32 bits (cujo limite superior é 2.147.483.647), mas esse recorde nós garantimos que ninguém conseguirá alcançar!

Ao terminar uma partida, o jogador somente registra seus pontos no Hall da Fama caso a sua pontuação seja alta o suficiente. Para simplificar, só são guardadas as cinco maiores pontuações, ou seja, você só armazena a sua pontuação caso ela seja maior que o menor dos recordes armazenados até então. O fluxograma da Figura 1 ilustra todo o processo que envolve uma partida.

 image001.gif

Figura 1. Fluxograma de todo o processo que envolve uma partida.

Se ao fim da partida você bateu um recorde, é exibida uma tela em que é possível entrar com seu nome, como mostra a Figura 2a. Nessa tela, escreve-se movimentando o botão direcional. Primeiro posiciona-se o cursor sobre uma das cinco posições possíveis, depois se escolhe o caractere movimentando o direcional para cima e para baixo. A posição selecionada tem a cor branca. Ao entrar com o seu nome, é exibida uma lista com os recordes locais (Figura 2b).

image005.gif

Figura 2. (a) Tela de inserção do nome e (b) tela de recordes locais.

Nesse ponto surge a pergunta: mas por que só é possível entrar com cinco caracteres para o nome? A resposta é simples, e quem já se aventurou a utilizar a classe Canvas para esse fim sabe disso. É muito complicado simular uma caixa de texto em Canvas, pois se devem capturar os eventos de teclado, pintar a letra digitada na tela e movimentar o cursor. Lembre-se que é possível digitar várias letras com a mesma tecla de um celular, imagine a complicação de escrever na tela um simples “abc”. Bem, é um trabalho possível, mas desnecessário para a nossa finalidade. Fica a cargo do leitor tentar implementar uma caixa de texto em Canvas (ler Nota 1).

 

Nota 1. Interface gráfica de alto nível

Para a criação de telas de entradas de dados no MIDP, existem componentes de interface gráfica chamados de componentes de alto nível. Com eles, é possível criar itens de formulário, como caixas de texto, o que simplificaria e muito o trabalho acima. Contudo o estudo de interface de alto nível está fora do escopo desse artigo. Para aqueles que se interessarem, busquem informações sobre o pacote javax.microedition.lcdui.*, que contém todas as classes que representam os componentes de alto nível, além da classe Canvas (de baixo nível) que estamos utilizando.

As novas funcionalidades

As principais características que deram interatividade ao jogo foram a contagem de pontos e o banco on-line de recordes. Para dar acesso a essas novas funcionalidades, foi criada uma opção no menu inicial chamada de Hall da Fama.

 

image007.gif
Figura 3. Hall da Fama

 

No Hall da Fama, você encontra as seguintes opções, conforme apresentado na Figura 3.

·         Recordes Locais: exibe os cinco recordes armazenados localmente. Como já foi dito, esse armazenamento é feito utilizando-se o RMS (assunto deste artigo);

·         Recordes On-line: exibe somente os cinco maiores recordes armazenados no servidor;

·         Enviar Recorde Atual: envia somente o maior recorde local. Portanto, antes de submeter o seu recorde, verifique se ele realmente é alto o suficiente, caso contrário, ele nem será exibido ao selecionar a opção Recordes On-line;

·         Local = On-line: torna os recordes locais iguais aos cinco maiores recordes on-line.

 

As três últimas opções (Recordes On-line, Enviar Recordes atual e Local) somente serão vistas no próximo artigo da série no qual será explicada com detalhes a comunicação entre celular e servidor.

Outra funcionalidade interessante foi a criação de várias fases. Quando todos os inimigos da tela são desativados, o método nextLevel() (não existente na primeira versão do artigo e que foi criado para atender a essa nova funcionalidade) da classe Engine é chamado. Esse método faz com que a thread de jogo entre no estado wait e altera os parâmetros que definem a dificuldade. O código da Listagem 1 mostra o método nextLevel().

 

Listagem 1. Método nextLevel() da classe Engine.

public void nextLevel(){       

        gameCanvas.novaFase = true;       

        fase++;

               

        if(fase % 2 == 0){

            linesOfEnemies++;

            maxEnemies = linesOfEnemies * ENEMIES_PER_LINE;

           

            enemyMaxBullets++;

            playerMaxBullets++;

            maxBullets = playerMaxBullets + enemyMaxBullets;

        }

       

        if(fase % 3 == 0){

            enemySpeed++;

        }                       

       

        numeroDeInimigos = maxEnemies;

        enemyNumeroDeBullets = 0;

       

        createSprites();       

        System.gc();

    }

 

A cada duas fases, incrementam-se as variáveis linesOfEnemies, enemyMaxBullets e playerMaxBullets, que correspondem a quantidade de linhas de inimigos, número máximo de tiros simultâneos dos inimigos e número máximo de tiros simultâneos do jogador, respectivamente. A cada três fases, incrementa-se a variável enemySpeed que representa a velocidade vertical dos inimigos. As variáveis maxEnemies e maxBullets representam a quantidade máxima de inimigos e de tiros na tela a cada fase. numeroDeInimigos e enemyNumeroDeBullets são usadas para controlar a quantidade de inimigos e de tiros inimigos ativos. É nesse método que devem ser feitas as alterações para configurar o nível de dificuldade do jogo. Veja na Figura 4 a evolução desses parâmetros da fase 1 para a fase 6.

 

image008.gif   image009.gif

Figura 4. Fase 1 x Fase 6.

 

Após a execução desse método, a thread de jogo exibe o número da fase e espera até que o usuário dê continuidade ao jogo, como mostra a Figura 5.

 

image010.gif

Figura 5. Início de uma nova fase.

Uma nota sobre jogabilidade

Ao dar mais funcionalidades para o game, devemos nos preocupar com sua jogabilidade. Jogabilidade aqui não se refere somente ao que acontece durante uma partida, mas também ao modo como a aplicação interage com o usuário. Todas as modificações no estado do jogo devem ser comunicadas adequadamente e seguindo um padrão.

Ao mudar de fase, o jogador é avisado e o jogo somente é reiniciado quando ele aperta no soft button “Continuar” ou quando ele começar a disparar contra os inimigos. Ao fim de uma partida, é exibida a mensagem de game over e o jogador deve optar por continuar. Não queremos que ele passe de fase ou que o jogo acabe sem que ele tenha conhecimento disso. Para implementar essa funcionalidade, a thread do jogo sofreu algumas mudanças, como mostra a ...

Quer ler esse conteúdo completo? Tenha acesso completo