Javafree

Jogos com MIDP 2.0: Personagens

Publicado por Tutoriais Admin em 17/08/2009 - 26.677 visualizações

Ricardo da Silva Ogliari

Resumo: O presente artigo objetiva demonstrar as diferenças da Canvas para a GameCanvas na construção de jogos, sendo que, tem um foco direcionado para a construção e manipulação de personagens, usando a classe Sprite. Para isso, demonstra inicialmente os conceitos básicos da GameCanvas, utilizando exemplos para melhor compreensão, em seguida disserta sobre a Sprite, mostrando a construção, transformação e animação dos personagens.

Baixe a Versão em PDF

Introdução

O desenvolvimento de jogos para celulares vem ganhando cada vez mais espaço, conseqüentemente, a plataforma J2ME também é exigida com maior intensidade. Pensando nisso, a MIDP ( Mobile Information Device Profile ) 2.0 traz um pacote direcionado exclusivamente aos jogos, a Game API, sendo que o mesmo se encontra em javax.microedition.lcdui.game .

Com a chegada desta API (Application Program interface), o desenvolvedor tem inúmeras vantagens, como por exemplo, uma facilidade maior na portabilidade dos jogos, isto porque, não será mais necessário o uso de bibliotecas de fabricantes para funcionalidades específicas, como é o caso dos Sprites. Ainda, a classe Canvas existente na MIDP 1.0 evolui para sua sucessora, a GameCanvas.

Este artigo mostrará o uso da GameCanvas e o gerenciamento de personagens, através da classe Sprite , tratando as principais diferenças existentes com a sua antecessora, a classe Canvas. Posteriormente, no próximo artigo, será detalhada a construção dos cenários dos jogos, também com a MIDP 2.0. Bons estudos.  

GameCanvas

A GameCanvas é uma das classes do pacote da Game API, da MIDP 2.0. Para melhor compreensão, imagine-a como uma melhoria na classe Canvas. Na programação de jogo, umas das suas principais funções é gerenciar o fluxo do jogo, veja Figura 1, também, é ela que gerencia o que será visto pelo usuário, já que detém uma instância da classe Graphics, e trabalha sobre ela. A Figura 2 ilustra o conjunto completo de classes da Game API.

Figura 1 - Lógica seqüencial de um jogo


Figura 2 - Classes da Game API

Fonte: Sabino (2006)

Em relação a sua antecessora, a GameCanvas tem algumas diferenças significativas, porém, este não é o foco deste artigo. A seguir, será mostrado uma listagem com um código básico para criar uma GameCanvas que possa gerenciar todo o fluxo do jogo. Veja a Listagem 1.

    public class Teste extends GameCanvas implements Runnable {

    private boolean rodando;

    private long delay = 20;

    public Teste () {

    super (true);

    }

    public void start () {

    rodando = true;

    Thread t = new Thread (this);

    t.start ();

    }

    public void stop () {rodando = false;}

    public void run () {

    Graphics g = getGraphics ();

    while (rodando) {

    input ();

    drawScreen (g);

    try {Thread.sleep (delay);}

    catch (InterruptedException ie) {}

    }

    }

    private void input () {

    int tecla = getKeyStates ();

    / / if ((tecla & LEFT_PRESSED)! = 0)

    }

    private void drawScreen (Graphics g) {

    g.setColor (0xffffff);

    flushGraphics ();

    }

    }

Listagem 1 - GameCanvas básico

 

Na primeira linha, é utilizado a palavra chave extends para definir a classe como uma GameCanvas , até este ponto não há nenhuma novidade. O método run da interface Runnable é de suma importância, pois é ele quem gerencia o fluxo do jogo, utilizando um laço controlado pelo valor booleano chamado de ? rodando?. No corpo do método run encontra-se uma chamada ao método input e ao método drawScreen , que servem para verificar as entradas do usuário e desenhar o buffer no display, respectivamente. Fazendo uma análise na figura 1 e comparando com a listagem 1, percebe-se que as duas seguem a mesma seqüência lógica.

Alguns pontos são relevantes e merecem uma atenção especial, no método input , que verifica as entradas do usuário, percebe-se uma diferença sensível em relação a Canvas, aqui utiliza-se o método getKeyStates (), que retorna o estado de todas as teclas. Na segunda linha do mesmo método é demonstrado como ficaria o código para verificar se a tecla direcional pra esquerda foi pressionada. Para finalizar a discussão, encontra-se o método flushGraphics no método drawScreen , este faz com que todo o screen buffer seja jogado para o display , sem ele a tela de desenho da GameCanvas não mostraria absolutamente nada.

Sprite

Um objeto Sprite é uma camada visual, representa uma imagem ou uma série delas. Este tipo de elemento visual é bastante usado para renderizar personagens do jogo, como uma nave espacial ou o monstro que deve ser combatido. Na MIDP 2.0, a classe Sprite tem vários métodos que facilitam o trabalho do desenvolvedor, dentre outros podemos citar: verificação da colisão de Sprites, métodos para transformação e para visualização em seqüência dos objetos, etc. A Figura 3 mostra um Sprite .


Figura 3 - Sprite

Fonte: Lam (2004)

Através de uma análise mais detalhada pode-se perceber que a figura 1 poderia perfeitamente ser desmembrada em partes de tamanhos iguais, e isso realmente pode ser feito na classe Sprite da MIDP 2.0, construindo partes da imagem chamadas de frames . Assim, torna-se possível à animação de imagens, simplesmente definindo uma seqüência de frames que devem ser mostrados no display . A Listagem 2 apresenta os construtores da classe Sprite.

    Sprite (Image img): Cria um Sprite a partir de uma imagem, não pode ser animado.

    Sprite (Sprite spr): Cria um novo Sprite de outro Sprite existente.

    Sprite (Image img, ing frameLargura, int frameAltura): Cria um Sprite que pode ser animado, ainda especifica-se a largura e a altura de cada frame.

Listagem 2 - Construtores da classe Sprite

 

Para animar um Sprite, é preciso criar uma seqüência de frames, ou seja, em cada instante uma parte da imagem estará sendo exibida, para isso, a Game API fornece um conjunto de métodos completos para gerenciar essa animação. É importante ressaltar que o número de frames será definido pela largura e altura de cada frame que foi especificado no construtor, por exemplo, se a imagem tem em sua totalidade, 160 pixeis e foi passado uma largura de 32 pixeis para o construtor, será criado um Sprite com 5 frames. Veja a Listagem 3 para conferir os métodos disponíveis na Game API.

    1. setFrameSequence (int [] sequência): configura uma seqüência de frames.

    2. getFrameSequenceLength (): retorna o número de elementos em uma seqüência de frames

    3. getFrame (): retorna o índice da seqüência de frames.

    4. nextFrame (): configura a seqüência de frames para mostrar o próximo frame, se a sequência está no último frame retorna para o primeiro.

    5. prevFrame (): configura a seqüência de frames para o frame anterior, se a seqüência está no primeiro frame vai para o último.

    6. setFrame (int indice): configura manualmente o frame que deve ser mostrado

Listagem 3 - Métodos da Game API para animação de imagens

Para animar um Sprite, os métodos mais importantes, são os de número 1, 4 e 5 da listagem 1, não necessariamente nesta ordem. O método setFrameSequence define uma seqüência de frames que será mostrado no display, e os métodos nextFrame ou prevFrame são usados para fazer com que o Sprite mostre em cada laço do jogo, um de seus frames .

Outra funcionalidade muito importante e útil, presente na API da classe Sprite , é a possibilidade de transformações (rotação), na imagem, através de um método apenas, o setTransform (int trans). O valor passado como inteiro define qual será a transformação aplicada sobre a imagem, felizmente a Game API definiu alguns valores constantes que podem ser usados para facilitar o desenvolvimento. Veja a tabela 1 para um melhor entendimento.

Valor estático Valor inteiro
TRANS_NONE 0
TRANS_MIRROR_ROT180 1
TRANS_MIRROR 2
TRANS_ROT180 3
TRANS_MIRROR_ROT270 4
TRANS_ROT90 5
TRANS_ROT270 6
TRANS_MIRROR_ROT90 7

Tabela 1 - Valores constantes para as transformações em objetos Sprite

Para encerrar o assunto sobre Sprite, é preciso demonstrar como é feito o tratamento de colisões, visto que, isso é de grande importância para o sucesso ou fracasso de um jogo. Assim como na maioria das operações especiais em um jogo, para esta, a classe Sprite também tem métodos disponíveis para verificar se dois objetos gráficos se chocaram. O método a ser usado é o collidesWith, veja a Listagem 4 para verificar suas duas formas. Na primeira forma é verificado se houve colisão com um elemento do tipo Image, nessa forma, é necessário identificar qual região da imagem será utilizada como região de colisão. Da segunda maneira, é verificado se houve colisão com outro elemento Sprite, em ambas as alternativas, é passado um valor boolean como parâmetro, este especifica se os pixeis opacos serão verificados ou não. Por exemplo, se o Sprite tem o formato de uma nave espacial, algumas áreas de seu retângulo serão pixeis que devem ser ignorados, se os mesmos forem transparentes pode-se passar um valor true para o método collidesWith para ele detectar a colisão somente quando o Sprite se chocar com a área da nave espacial, eu não com seus pixeis transparentes.

    CollidesWith (Image imagem, int x, int y, boolean pixel)

    CollidesWith (Sprite sprite, boolean pixel);

Listagem 4 - Métodos da classe Sprite para verificação de colisão entre elementos gráficos

Para facilitar a compreensão dos conceitos apresentados no parágrafo anterior, veja a Figura 4. Passando um valor false no último parâmetro do método collidesWitth , o mesmo retornaria um valor verdadeiro, indicando que houve colisão, porém, perceba que apenas as áreas retangulares dos objetos se tocaram, mas os personagens não, para resolver este impasse, passe um valor true para o método.


Figura 4 - Colisão de Sprite

 

Conclusão

Para os desenvolvedores de jogos desde a época da MIDP 1.0, este artigo surpreende pelas facilidades encontradas na MIDP 2.0, para os iniciantes, é um bom início no mundo dos jogos. Independente do leitor, o texto visou uma breve explicação da construção de personagens com a Game API, que fornece muitas melhorias e facilidades na programação, estimulando ainda mais uma área em franca expansão, o desenvolvimento de jogos para telefones celulares.

 

Bibiografia

LAN, Jason. J2ME & Gaming. Livro em PDF sobre jogos em J2ME. Disponível em www.jasonlam604.com / books.php

SABINO, Vanessa Cristina (2006). Game API: Simplicidade e Poder nos Jogos para Celulares. Disponível em http://midia.linuxchix.org.br/artigos/GameAPI-unificado.pdf . Acesso em Maio de 2006.

comentários: 0