• Cen�rio

    Muitas vezes queremos construir jogos mais complicados. Mas montar um jogo de labirinto por exemplo com o que voc� leu at� agora, n�o seria uma tarefa f�cil. Para isso n�s usamos um cen�rio.

    No Jplay existe uma classe chamada Scene que � utilizada para a constru��o de cen�rios.

    1 - Antes de come�ar a construir o c�digo

    Antes de escrever qualquer linha de c�digo pense em como o seu cen�rio �, quais s�o as imagens est�ticas (n�o animadas), quais as imagens din�micas como sprites e animations. As imagens est�ticas ser�o as que estar�o inseridas no arquivo que comp�e a cena.

    Tenha em mente que todas as imagens do cen�rio devem ter a mesma dimens�o, se voc� tem imagens que s�o ret�ngulos ent�o todas devem ser ret�ngulos.

    Feito isso, voc� est� pronto para come�ar a constru��o do arquivo do seu cen�rio. As se��es 2 e 3 cuidam dessa constru��o.

    2 - Organiza��o do arquivo do cen�rio

    No Jplay as informa��es para a constru��o do cen�rio s�o quardadas em um arquivo com a extens�o '.scn'.

    O arquivo � organizado da seguinte forma:

    linha 1 - n�mero de imagens usadas para a constru��o do cen�rio (as imagens est�ticas).
    linha 2 - caminho da primeira imagem e sua extens�o
    linha 3 - caminho da segunda imagem e sua extens�o
    linha 4 - caminho da terceira imagem e sua extens�o
    linha n+1 - caminho da n-�sima imagem e sua extens�o
    linha n+2 - come�o da constru��o da matriz
    linha m - fim da constru��o da matriz que � representada pelo caracter '%'.
    linha m+1 - caminho do backdrop e sua extens�o.

    Obs.: N�o deixe nenhuma linha em branco pois, isso gerar� um erro de execu��o.

    Exemplo de uma arquivo '.scn'.

    1. 3  
    2. wall.jpg  
    3. floor.jpg  
    4. star.jpg  
    5. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  
    6. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  
    7. 0,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0  
    8. 0,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,1,0  
    9. 0,1,2,1,2,2,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,1,0  
    10. 0,1,2,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,2,2,2,2,1,0  
    11. 0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,0  
    12. 0,1,2,1,1,1,1,2,2,2,1,1,1,1,1,1,2,2,1,1,1,2,1,0  
    13. 0,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,0  
    14. 0,1,2,1,2,2,2,1,2,2,2,2,2,2,2,1,1,1,1,1,2,2,1,0  
    15. 0,1,2,1,2,2,2,1,1,1,1,1,1,1,2,1,2,2,2,1,2,2,1,0  
    16. 0,1,2,1,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,1,1,1,1,0  
    17. 0,1,2,1,2,2,2,2,2,2,1,2,2,2,2,1,2,2,2,2,2,2,1,0  
    18. 0,1,2,1,1,1,2,2,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,0  
    19. 0,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,3,0  
    20. 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  
    21. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  
    22. %  
    23. backdrop.jpg              

    3 - Construindo a matriz

    A matriz � composta por n�meros inteiros separados por virgula e sem espa�os entre eles.

    O n�mero 0 (zero) sempre corresponde ao backdrop (a imagem que ser� desenhada por baixo do cen�rio).

    J� os outros n�mero seguem a seguinte l�gica:
    1 - representa a imagem wall.jpg
    2 - representa a imagem flor.jpg
    3 - representa a imagem star.jpg

    Colocamos o n�mero 0 (zero) nas bordas sinalizando que essa � uma �rea do backdrop.

    O n�mero 1 � usado como 'wall' e delimita passagens.
    O n�mero 2 � usado como lugares pecorr�veis.
    O n�mero 3 � usado como ponto final de chegada.

    4 - Construindo o c�digo para mostrar um cen�rio

    Para construir o c�digo n�s usaremos os seguintes m�todos da classe Scene:

    1. //Construtor da classe  
    2. public Scene();  
    3.   
    4. //Ccarrega as informa��es armazenadas no arquivo '.scn'.  
    5. public void loadFromFile(String fileName);  
    6.   
    7. //Informa ao Jplay quais s�o as coordenadas iniciais onde o cen�rio dever� ser desenhado inicialmente.  
    8. public void setDrawStartPos(int drawStartX, int drawStartY);  
    9.   
    10. //Desenha o cen�rio na tela  
    11. public void draw();  
    12.    

    Exemplo: Mostrando um cen�rio na tela.

    1. package cenario;  
    2.   
    3. import java.awt.Point;  
    4. import java.util.Vector;  
    5. import jplay.Keyboard;  
    6. import jplay.Scene;  
    7. import jplay.TileInfo;  
    8. import jplay.Window;  
    9.   
    10. /** 
    11.  * @author Gefersom Cardoso Lima 
    12.  * Federal Fluminense University 
    13.  * Computer Science 
    14.  */  
    15.    
    16. public class Cenario {  
    17.   
    18.     private Window window;  
    19.     private Scene scene;  
    20.       
    21.     public Cenario()  
    22.     {  
    23.             window = new Window(800,600);  
    24.             scene = new Scene();  
    25.             scene.loadFromFile("scene.scn");  
    26.             scene.setDrawStartPos(1530);  
    27.   
    28.     }  
    29.   
    30.     public void run()  
    31.     {  
    32.             while(true)  
    33.             {  
    34.                 scene.draw();  
    35.                 window.update();                              
    36.             }  
    37.     }  
    38.       
    39.     /** 
    40.      * @param args the command line arguments 
    41.      */  
    42.     public static void main(String[] args) {  
    43.         Cenario cen = new Cenario();  
    44.         cen.run();  
    45.     }         
    46. }  
    47.    

    5 - Adicionando um objeto ao cen�rio.

    Para adicionar um objeto que ser� controlado por n�s ao cen�rio usamos o m�todo abaixo:

    1. //Adiciona qualquer GameObject do Jplay ao cen�rio mas, n�o modifica a   
    2. //matriz que � usada para a constru��o do cen�rio.  
    3. public void addOverlay(GameObject overlay);  
    4.    

    Com o m�todo acima podemos adicionar um GameImage, uma Animation ou um Sprite ao cen�rio.

    6 - A classe auxiliar TileInfo.

    Quando o Jplay l� o arquivo de entrada do cen�rio ele cria para cada valor inteiro da matriz armazenada no arquivo '.scn' um TileInfo.

    As informa��es armazenadas no TileInfo s�o: 'id' - valor num�rico que representa a imagem e uma refer�ncia para a imagem.

    Todos os TileInfos s�o armazenados em um matriz usada internamente pela classe Scene.

    Exemplo:

    A imagem 'wall.jpg' � presentando pelo n�mero 1.
    O Jplay cria um TileInfo com a ID = 1 e associa esse TileInfo a imagem 'wall.jpg' que � armazenada em outra estrutura interna na classe Scene.

    � por meio do TileInfo que podemos saber onde um determinado overlay est� localizado e quais s�o as imagens sobrepostas por ele ou em volta dele.

    7 - Delimitando �reas pecorr�veis.

    M�todo da classe Scene usados nessa se��o:

    1. //Retorna os objetos que est�o entre os ponto passados como par�metros.  
    2. public Vector getTilesFromRect(Point min, Point max)  

    Se n�o delimitarmos �reas em que o GameObject (adicionado com o m�todo addOverlay()) pode percorrer ele se mover� por todo o cen�rio.

    Para fazer o GameObject se mover somente por algumas �reas seguimos os seguinte passos:

    1 - Capturamos os valores m�nimos e m�ximos para as coordenadas do GameObject.

    1. //Lembre-se que as coordenadas de todo GameObject no Jplay s�o n�meros no formato 'double'  
    2. //logo, algumas vezes precisaremos fazer um cast para um n�mero inteiro.  
    3.   
    4. //Posicao min � a posi��o (x,y) do GameObject             
    5. Point playerMin = new Point ((int)gameObject.x, (int)gameObject.y);  
    6.   
    7. //Posicao max � a posi��o (x + largura, y + altura) do GameObject  
    8. Point playerMax = new Point((int)(gameObject.x + player.width), (int)(gameObject.y + gameObject.height));  

    2 - Capturamos as imagens que est�o na mesma �rea do GameObject.

    1. //Retorna as imagens que estiverem na mesma �rea do GameObject (x,y), (x + largura, y + altura)  
    2. Vector tiles = scene.getTilesFromRect(playerMin, playerMax);              

    3 - Para cada tile retornado verificamos qual � o tile a partir da sua id e se o player colidiu com ele.

    Depois do teste de colis�o e de verifica��o de id o que ser� feito � uma escolha do programador.

    No trecho abaixo o GameObject somente � reposicionado alguns pixels. J� que para haver uma colis�o alguns pixels t�m que ser sobrepostos. Caso n�o fizessemos isso o GameObject ficaria colidindo infinitamente com o TileInfo.

    1. //para todos os tiles  
    2. for(int i = 0 ; i < tiles.size() ; i++)  
    3. {  
    4.     TileInfo tile = (TileInfo)tiles.elementAt(i);  
    5.       
    6.     //se o tile � parede e o player colidiu com ele  
    7.     if((tile.id == Constante.TILE_WALL) && player.collided(tile))  
    8.     {  
    9.             //se o player est� se movendo na diagonal  
    10.             if (player.moveuNaHorizontal())  
    11.             {  
    12.                     //o player est� atr�s da parede?  
    13.                     if(player.x  <= tile.x -1)  
    14.                         player.x = tile.x - player.width;//Reposiciona o player  
    15.                     else  
    16.                         //o player est� na frente da parede  
    17.                         player.x = tile.x + tile.width;//Reposiciona o player  
    18.             }  
    19.             else  
    20.             {       //o player est� abaixo da parede?  
    21.                     if(player.y >= tile.y  + tile.height -1)  
    22.                         player.y = tile.y + tile.height;//Reposiciona o player  
    23.                     else  
    24.                         //o player est� acima da parede  
    25.                         player.y = tile.y - player.height ;//Reposiciona o player  
    26.             }  
    27.             return false;  
    28.     }  
    29.     else  
    30.         //se o player encontrou a estrela  
    31.         if(tile.id == Constante.TILE_STAR)  
    32.             return true;  
    33. }  
    34. return  false;  
    35.               

    Exemplo:

    1. import jplay.Keyboard;  
    2. import jplay.Sprite;              
    3. import java.awt.Point;  
    4. import java.util.Vector;  
    5. import jplay.Keyboard;  
    6. import jplay.Scene;  
    7. import jplay.TileInfo;  
    8. import jplay.Window;  
    9.   
    10. /*----------------------------------------------------------------------------------------------*/  
    11.   
    12. public class Constante   
    13. {  
    14.         public static int TILE_WALL = 1;  
    15.         public static int TILE_STAR = 3;  
    16. }             
    17.   
    18. /*----------------------------------------------------------------------------------------------*/  
    19.   
    20. public class Player extends Sprite  
    21. {  
    22.         private boolean horizontalMoveKeyPressed;  
    23.           
    24.         public Player()  
    25.         {  
    26.                 super("player.png",8);  
    27.         }  
    28.   
    29.         public boolean moveuNaHorizontal()  
    30.         {  
    31.                 return horizontalMoveKeyPressed;  
    32.         }  
    33.           
    34.         public void move(Keyboard keyboard)  
    35.         {  
    36.                 horizontalMoveKeyPressed = true;  
    37.                 if(keyboard.keyDown(Keyboard.LEFT_KEY) == true)  
    38.                 {  
    39.                     this.x -= 1;  
    40.                     setCurrFrame(2);  
    41.                 }  
    42.                 else  
    43.                     if(keyboard.keyDown(Keyboard.RIGHT_KEY) == true)  
    44.                     {  
    45.                         this.x += 1;  
    46.                         setCurrFrame(3);  
    47.                     }  
    48.                     else  
    49.                         horizontalMoveKeyPressed = false;  
    50.   
    51.                 if (!horizontalMoveKeyPressed)  
    52.                 {  
    53.                     if(keyboard.keyDown(Keyboard.UP_KEY) == true)  
    54.                     {  
    55.                         this.y -= 1;  
    56.                         setCurrFrame(0);  
    57.                     }  
    58.                     else  
    59.                         if(keyboard.keyDown(Keyboard.DOWN_KEY) == true)  
    60.                         {  
    61.                             this.y += 1;  
    62.                             setCurrFrame(1);  
    63.                         }  
    64.                 }  
    65.         }  
    66. }             
    67.   
    68. /*----------------------------------------------------------------------------------------------*/  
    69.   
    70. public class Cenario   
    71. {  
    72.     private Window window;  
    73.     private Keyboard keyboard;  
    74.     private Scene scene;  
    75.     private Player player;  
    76.       
    77.     public Cenario()  
    78.     {  
    79.             window = new Window(800,600);  
    80.             keyboard = window.getKeyboard();  
    81.             scene = new Scene();  
    82.             scene.loadFromFile("scene.scn");  
    83.             scene.setDrawStartPos(1530);  
    84.   
    85.             player = new Player();  
    86.             player.x = 454;  
    87.             player.y =  140;  
    88.             scene.addOverlay(player);  
    89.     }  
    90.   
    91.     public void run()  
    92.     {  
    93.             boolean loop = true;  
    94.             while(loop)  
    95.             {  
    96.                 draw();  
    97.                 controlarCaminho();  
    98.                 player.move(keyboard);  
    99.   
    100.                 if (keyboard.keyDown(Keyboard.ESCAPE_KEY))  
    101.                     loop = false;  
    102.                 window.delay(10);  
    103.             }  
    104.             window.exit();  
    105.     }  
    106.   
    107.     public void draw()  
    108.     {  
    109.             scene.draw();  
    110.             window.update();  
    111.     }  
    112.   
    113.     boolean controlarCaminho()  
    114.     {  
    115.             //Posicao min � a posi��o (x,y) do player  
    116.             //Posicao max � a posi��o (x + largura, y + altura) do player  
    117.             Point playerMin = new Point ((int)player.x, (int)player.y);  
    118.             Point playerMax = new Point((int)(player.x + player.width), (int)(player.y + player.height));  
    119.   
    120.             //Retorna as imagens que estiverem na mesma �rea do player (x,y), (x + largura, y + altura)  
    121.             Vector tiles = scene.getTilesFromRect(playerMin, playerMax);  
    122.   
    123.             //para todos os tiles  
    124.             for(int i = 0 ; i < tiles.size() ; i++)  
    125.             {  
    126.                 TileInfo tile = (TileInfo)tiles.elementAt(i);  
    127.                   
    128.                 //se o tile � parede e o player colidiu com ele  
    129.                 if((tile.id == Constante.TILE_WALL) && player.collided(tile))  
    130.                 {  
    131.                         //se o player est� se movendo na diagonal  
    132.                         if (player.moveuNaHorizontal())  
    133.                         {  
    134.                                 //o player est� atr�s da parede?  
    135.                                 if(player.x  <= tile.x -1)  
    136.                                     player.x = tile.x - player.width;//Reposiciona o player  
    137.                                 else  
    138.                                     //o player est� na frente da parede  
    139.                                     player.x = tile.x + tile.width;//Reposiciona o player  
    140.                         }  
    141.                         else  
    142.                         {       //o player est� abaixo da parede?  
    143.                                 if(player.y >= tile.y  + tile.height -1)  
    144.                                     player.y = tile.y + tile.height;//Reposiciona o player  
    145.                                 else  
    146.                                     //o player est� acima da parede  
    147.                                     player.y = tile.y - player.height ;//Reposiciona o player  
    148.                         }  
    149.                         return false;  
    150.                 }  
    151.                 else  
    152.                     //se o player econtrou a estrela  
    153.                     if(tile.id == Constante.TILE_EXIT)  
    154.                         return true;  
    155.             }  
    156.             return  false;  
    157.     }  
    158.       
    159.     /** 
    160.      * @param args the command line arguments 
    161.      */  
    162.     public static void main(String[] args) {  
    163.             Cenario cen = new Cenario();  
    164.             cen.run();  
    165.     }  
    166. }     
    167.    

    8 - Todos os m�todos da classe Scene.

    1. //Construtor da classe  
    2. public Scene();  
    3.   
    4. //Carrega as informa��es armazenadas no arquivo '.scn'.  
    5. public void loadFromFile(String sceneFile);  
    6.   
    7. //Adiciona qualquer GameObject do Jplay ao cen�rio mas, n�o modifica a   
    8. //matriz que � usada para a constru��o do cen�rio.  
    9. public void addOverlay(GameObject overlay);  
    10.   
    11. //Informa ao Jplay quais s�o as coordenadas iniciais onde o cen�rio dever� ser desenhado inicialmente.  
    12. public void setDrawStartPos(int drawStartX, int drawStartY);  
    13.   
    14. //Desenha o cen�rio na tela  
    15. public void draw();  
    16.   
    17. //Retorna um tile da matrix de tiles especificado pela sua linha e coluna na matrix,   
    18. //caso a linha ou a coluna n�o existam retorn null.  
    19. public TileInfo getTile(int row, int colunm);  
    20.   
    21. //Retorna os objetos que est�o entre os ponto passados como par�metros.  
    22. public Vector getTilesFromRect(Point min, Point max);  
    23.   
    24. //Retorna os objetos que est�o entre os ponto passados como par�metros   
    25. //(deve ser usado em substitui��o � fun��o anterior, em jogos do tipo side scrolling).  
    26. public Vector getTilesFromPosition(Point min, Point max);  
    27.   
    28. //Remove um tile da matrix de tiles especificado pela sua linha e coluna na matrix.  
    29. public void removeTile(int row, int colunm);  
    30.   
    31. //Troca a ID do tile especificado pela sua linha e coluna pela ID de um outro tile.  
    32. public void changeTile(int row, int colunm, int newID);  
    33.   
    34. //Salva o estado corrente da Scene em arquivo para posterior recupera��o, os overlays n�o ser�o salvos.  
    35. public void saveToFile(String fileName);  
    36.   
    37. //Move o cenario de forma a centralizar o object passado como par�metro.  
    38. public void moveScene(GameObject object);  
    39.   
    40. //Retorna a �ltima movimenta��o do cen�rio no eixo x.  
    41. public double getXOffset();  
    42.   
    43. //Retorna a �ltima movimenta��o do cen�rio no eixo y.  
    44. public double getYOffset();  
    45.    

    UFF - Universidade Federal Fluminense - Institudo de Computação - Ciência da Computação