J2ME/Lições/LayerManager

Origem: Wikilivros, livros abertos por um mundo aberto.

Já vimos como mostrar gráficos na nossa tela, agora iremos ver algo mais relacionado ao desenvolvimento de jogos em 2D utilizando as classes TiledLayer, Sprite e LayerManager.

Tiles podem ser compreendidos como blocos usados para a construção de cenários estáticos em jogos 2D, a técnica de construção usando Tiles é praticamente a mesma em qualquer plataforma, cria-se um objeto e utiliza-se um vetor para posicionar os Tiles no cenário. Sprites são os seres dinâmicos do jogo como personagens, inimigos, objetos móveis, etc. No J2ME temos a classe LayerManager que serve para controlar e mostrar o mundo do jogo construído através de Tiles e Sprites.

TiledLayer[editar | editar código-fonte]

Vamos começar utilizando a mesma estrutura do GameCanvas.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Primeiramente precisamos carregar a imagem onde estão desenhados os tiles, para isso vamos instanciar e criar o objeto do tipo Image como vimos anteriormente.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();

     Image minhaImagem;
     
     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora vamos instanciar a variável do tipo TiledLayer.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagem;
     TiledLayer meuTiledLayer;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora dentro do método run() vamos criar o objeto TiledLayer, vamos entrar com 4 parâmetros: O primeiro é a quantidade de linhas que o cenário vai ter. O segundo é q quantidade de colunas que o cenário vai ter. O terceiro é o objeto Image carregado. O quarto é a largura em pixels de cada tile. O quinto é a altura em pixels de cada tile.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagem;
     TiledLayer meuTiledLayer;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagem, 16, 16);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora para vamos criar o vetor para desenharmos a grade de tiles, para isso devemos criar um vetor do tipo int[] e colocar o valor correspondente ao tile, lembre-se que no nosso exemplo usamos uma grade de no máximo 5x5 tiles.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagem;
     TiledLayer meuTiledLayer;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagem, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora com o vetor da grade já criado, devemos inseri-lo dentro do objeto TiledLayer, a inserção é feita através do método setCell() onde inserimos cada célula individualmente, para isso vemos criar um laço for criando uma variável de zero até menor que grade.length.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagem;
     TiledLayer meuTiledLayer;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagem, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
             }
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora dentro do laço for vamos finalmente usar o método setCell() da classe TiledLayer utilizando os seguintes atributos: Primeiro a linha em que está sendo inserido. Segundo a coluna em que está sendo inserido. Terceiro o valor do tile (a célula do vetor grade[]).

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagem;
     TiledLayer meuTiledLayer;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagem, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Sprite[editar | editar código-fonte]

Sprites são imagens com animação geralmente usados como personagens, inimigos ou objetos móveis, vamos ver como implementa-los no J2ME. Inicialmente vamos carregar a imagem onde está desenhado o Sprite, para isso vamos instanciar e criar um objeto do tipo Image como vimos anteriomente.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();

     Image minhaImagem;
     
     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora vamos instanciar a variável do tipo Sprite.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();

     Image minhaImagem;
     Sprite meuSprite;
     
     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora dentro do método run() vamos criar o objeto do tipo Sprite, vamos entrar 3 parâmetros: Primeiro o objeto do tipo Image. Segundo a largura em pixels de cada cena. Terceiro a altura em pixels de cada cena.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();

     Image minhaImagem;
     
     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagem = minhaImagem.createImage("/Minha Imagem.png");
             meuSprite = new Sprite(minhaImagem, 32, 32);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

LayerManager[editar | editar código-fonte]

Vimos como carregar e criar Tiles e Sprites, agora vamos ver como coloca-los para serem exibidos na tela, para isso iremos ver como usar o LayerManager. Para começar vamos instanciar e inicializar os objetos do tipo TiledLayer e Sprite vistos anteriormente.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagemTile;
     TiledLayer meuTiledLayer;
     Image minhaImagemSprite;
     Sprite meuSprite;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagemTile = minhaImagemTile.createImage("/Minha Imagem tile.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagemTile, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
             minhaImagemSprite = minhaImagemSprite.createImage("/Minha Imagem sprite.png");
             meuSprite = new Sprite(minhaImagemSprite, 32, 32);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora para começarmos a controlar a exibição de Tiles e Sprites primeiramente devemos instanciar uma variável do tipo LayerManager.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagemTile;
     TiledLayer meuTiledLayer;
     Image minhaImagemSprite;
     Sprite meuSprite;
     LayerManager meuLayerManager;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagemTile = minhaImagemTile.createImage("/Minha Imagem tile.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagemTile, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
             minhaImagemSprite = minhaImagemSprite.createImage("/Minha Imagem sprite.png");
             meuSprite = new Sprite(minhaImagemSprite, 32, 32);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora dentro do run() vamos criar o objeto do tipo LayerManager

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagemTile;
     TiledLayer meuTiledLayer;
     Image minhaImagemSprite;
     Sprite meuSprite;
     LayerManager meuLayerManager;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagemTile = minhaImagemTile.createImage("/Minha Imagem tile.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagemTile, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
             minhaImagemSprite = minhaImagemSprite.createImage("/Minha Imagem sprite.png");
             meuSprite = new Sprite(minhaImagemSprite, 32, 32);
             meuLayerManager = new LayerManager();
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora vamos colocar organizar os objetos do tipo Sprite e TiledLayer para serem exibidos, para isso vamos usar o método append() da classe LayerManager, note que quando se pintar a tela a ordem dos elementos inseridos irá influenciar o que será exibido em cima do outro, sempre o primeiro objeto colocado no append() será o que ficará sempre visível, nesse exemplo vamos insrir na ordem, meuSprite -> meuTile.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagemTile;
     TiledLayer meuTiledLayer;
     Image minhaImagemSprite;
     Sprite meuSprite;
     LayerManager meuLayerManager;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagemTile = minhaImagemTile.createImage("/Minha Imagem tile.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagemTile, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
             minhaImagemSprite = minhaImagemSprite.createImage("/Minha Imagem sprite.png");
             meuSprite = new Sprite(minhaImagemSprite, 32, 32);
             meuLayerManager = new LayerManager();
             meuLayerManager.append(meuSprite);
             meuLayerManager.append(meuTile);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Agora colocaremos a cena para ser exibida na tela, dentro do loop principal vamos usar o método paint() da classe LayerManager e entrar como parâmetros: 1º o objeto do tipo Graphics. 2º o pixel x de onde a cena começará a ser exibida. 3º o pixel y de onde a cena começará a ser exibida.

 import javax.microedition.lcdui.game.*;
 import javax.microedition.lcdui.*;
 
 public class MeuGameCanvas extends GameCanvas implements Runnable {
     Thread meuThread;
     Graphics meuGrafico = this.getGraphics();
     
     Image minhaImagemTile;
     TiledLayer meuTiledLayer;
     Image minhaImagemSprite;
     Sprite meuSprite;
     LayerManager meuLayerManager;

     public MeuGameCanvas(){
         super(false);
         meuThread = new Thread(this);
         meuThread.start();
     }
     public void run(){
         try{
             minhaImagemTile = minhaImagemTile.createImage("/Minha Imagem tile.png");
             meuTiledLayer = new TiledLayer(5, 5, minhaImagemTile, 16, 16);
             int grade[] = { 2, 1, 1, 1, 3,
                             1, 0, 0, 0, 1,
                             1, 0, 1, 0, 1,
                             1, 0, 0, 0, 1,
                             4, 1, 1, 1, 5 };
             for(int i=0; i<grade.length; i++){
                 meuTiledLayer.setCell(i%6, i/6, grade[i]);
             }
             minhaImagemSprite = minhaImagemSprite.createImage("/Minha Imagem sprite.png");
             meuSprite = new Sprite(minhaImagemSprite, 32, 32);
             meuLayerManager = new LayerManager();
             meuLayerManager.append(meuSprite);
             meuLayerManager.append(meuTile);
         }catch(Exception ex){
             ex.printStackTrance();
         }
         boolean fimDeJogo = false;
         while(fimDeJogo == false){
             try{
                 meuLayerManager.paint(meuGrafico, 0, 0);
                 meuThread.sleep(50);
             }(catch Exception minhaEscessao){
                 minhaExcessao.printStackTrance();
             }finally{
                 flushGraphics();
             }
         }
     }
 }

Colisão[editar | editar código-fonte]