Pages

Banner

quinta-feira, 7 de junho de 2012

JAVA GAMES 2D::Estrutura Básica do Game::03

"


Nesse III tutorial vamos aprender a criar a estrutura básica para os nossos jogos, definir o tamanho da janela(Frame), criar um Image Buffering e o gameLoop e etc...
Explicando algumas coisas:
Ao criarmos um código que por exemplo: movimente uma nave inimiga em um jogo como Space invader, para que a nave mova-se constantemente, o código que faz esse controle precisa ser executado constantemente, um outro exemplo: ao pressionar uma tecla para mover um personagem, os valores das variáveis que guardam sua posição X e Y seriam modificados, a imagem que aparece na tela precisa ser atualizada, para exibir o personagem em sua nova posição, então para que isso aconteça precisamo criar uma coisa chamamos de game loop, que seria nada mais do que um loop infinito!

while(true){
  //COMANDO!
}

Outro detalhe importante do game loop, precisamos controlar a frequência com que a tela será atualizada e os métodos de controle interno do jogo! para isso usaremos o seguinte código:

int FPS = 30; //TAXA DE ATUALIZAÇÃO DA TELA
while(true){
  Thread.sleep(1000/FPS);
}

O método sleep() receberá como parâmetro, um valor inteiro que será o tempo em milissegundos de uma PAUSA que ocorrerá! porem esse é um código perigoso que estamos mando nossa aplicação executar, teremos então que tratar as exceções que poderão ocorrer, ficando assim:


int FPS = 30; //TAXA DE ATUALIZAÇÃO DA TELA
while(true){
  try{
    Thread.sleep(1000/FPS);
  }catch(){
    System.out.println("Erro na Thread!"); 
    //MENSAGEM A SER EXIBIDA NO CONSOLE CASO OCORRA ALGUM ERRO
  }
}


Outro detalhe importante na construção de games é, ao mandarmos desenhar algum objeto na tela, como um texto, imagem, forma geométrica, etc, devido ao game loop ficar atualizando a tela o tempo inteiro, dará uma sensação de leg, porque será desenhado na tela elemento a elemento, então qual seria uma solução para esse probleminha?
O Image Buffering, iremos criar um BufferedImage (buffer de imagem)!!!, como é que isso funciona?
Bem é o seguinte... não iremos mais desenhar elementos na tela, ao invés disso iremos desenhar os elementos no buffer, e por fim desenhar o que está no buffer na tela de uma vez só!

então ai segue o corpo do nosso game totalmente comentado:


import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
//A CLASSE GAME HERDA AS FUNCIONALIDADES DE JFRAME
public class Game extends JFrame {

 BufferedImage backBuffer; //ESSE É O NOSSO BUFFER
 int FPS = 30;    //ESSA É A TAXA DE ATUALIZAÇÃO DA TELA
 int janelaW = 500;   //LARGURA DA TELA
 int janelaH = 500;   //ALTURA DA TELA

 //NO NOSSO METODO ATUALIZAR VAMOS CHAMAR OS METODOS
 //QUE SERÃO EXECUTADOS O TEMPO INTEIRO...
 public void atualizar() {

 }

 //NESSE MÉTODO VAMOS DESENHAR
 //FORMAS GEOMETRICAS, IMAGENS E TEXTOS NA TELA E ETC...
 public void desenharGraficos() {
  Graphics g = getGraphics();//COM g IREMOS DESENHAR O QUE ESTÁ NO BUFFER NA TELA
  Graphics bbg = backBuffer.getGraphics();//COM bbg IREMOS DESENHAR NO NOSSO BUFFER
  
  //AQUI ESTAMOS DESENHANDO O BUFFER NA TELA,
  //NAS COORDENADAS X:0 e Y:0
  g.drawImage(backBuffer, 0, 0, this);
 }
 //ESSE É O NOSSO MÉTODO INICIALIZAR
 //AQUI VAMOS INICIALIZAR ALGUMAS CONFIGURAÇÃO DO frame E OUTRAS CONFIGURAÇÕES
 public void inicializar() {
  setTitle("Titulo do Jogo!");//SETANDO O TITULO DA JANELA
  setSize(janelaW, janelaH);//DEFINIDO AS DIMENSÕES DA JANELA
  setResizable(false);//TIRANDO A PERMISSÃO DO USUÁRIO REDIMENSIONAR A JANELA
  setDefaultCloseOperation(EXIT_ON_CLOSE);//QUANDO FECHARMOS O frame A APLICAÇÃO PARA DE EXECUTAR
  setLayout(null);//COM ISSO PODEREMOS DEFINIAR COORDENADA E DIMESÕES DE ELMENTOS DE FORMULARIO NO NOSSO FRAME
  setVisible(true);//MUDANDO A VISIBILIDADE DO frame PARA TRUE, ASSIM ELE APARECERÁ
  backBuffer = new BufferedImage(janelaW, janelaH, BufferedImage.TYPE_INT_RGB);//CRIANDO O NOSSO BUFFER DE IMAGEM
 }
 //AQUI É O NOSSO MÉTODO RUN()
 //NELE TEMOS O NOSSO GAME LOOP (UM LOOP INFINITO)
 public void run() {
  inicializar();//AQUI CHAMAMOS O METODO INICIALIZAR SOMENTE UMA VEZ, POIS ELE ESTÁ FORA DO NOSSO LOOP
  while (true) {//AQUI É O NOSSO LOOP INFINITO
   atualizar();//CHAMAMOS O METODO ATUALIZAR O TEMPO INTEIRO
   desenharGraficos();//ATUALIZAREMOS O GRÁFICO QUE APARECE NA TELA O TEMPO INTEIRO
    try {
     Thread.sleep(1000/FPS); //TAXA DE ATUALIZAÇÃO NA TELA, FUNCIONA COMO UM DELAY
    } catch (Exception e) {
     System.out.println("Thread interrompida!");
    }
  }
 }
 //AQUI É O NOSSO MÉTODO PRINCIPAL
 public static void main(String[] args) {
  Game game = new Game();//CRIAMOS UM OBJETO A PARTIR DESSA PROPRIA CLASSE
  game.run();//CHAMAMOS O METODO RUN(), O MÉTODO RUN() EXECUTA O INICIALIZAR(), ATUALIZAR() E DESENHARGRAFICOS()
 }
 //-----------------------------------------------------------------------------
}// FIM DO CÓDIGO FONTE

Outro pequeno detalhe importante...
Como vamos desenvolver Games 2D, estaremos trabalhando dentro de um plano cartesiano... pra quem não sabe o plano cartesiano foi criado por René Descartes e consiste em em dois eixos perpendiculares um X e outro Y....

porem ....... aqui vai funcionar de uma maneira um pouquinho diferente....


É assim que vamos nos locomover dentro desse plano bidimensional !!!
Então é isso pessoal! continuem no próximo Tutor...

\_(^_^)_/ Comentários em baixo \_(^_^)_/
"


Nesse III tutorial vamos aprender a criar a estrutura básica para os nossos jogos, definir o tamanho da janela(Frame), criar um Image Buffering e o gameLoop e etc...
Explicando algumas coisas:
Ao criarmos um código que por exemplo: movimente uma nave inimiga em um jogo como Space invader, para que a nave mova-se constantemente, o código que faz esse controle precisa ser executado constantemente, um outro exemplo: ao pressionar uma tecla para mover um personagem, os valores das variáveis que guardam sua posição X e Y seriam modificados, a imagem que aparece na tela precisa ser atualizada, para exibir o personagem em sua nova posição, então para que isso aconteça precisamo criar uma coisa chamamos de game loop, que seria nada mais do que um loop infinito!

while(true){
  //COMANDO!
}

Outro detalhe importante do game loop, precisamos controlar a frequência com que a tela será atualizada e os métodos de controle interno do jogo! para isso usaremos o seguinte código:

int FPS = 30; //TAXA DE ATUALIZAÇÃO DA TELA
while(true){
  Thread.sleep(1000/FPS);
}

O método sleep() receberá como parâmetro, um valor inteiro que será o tempo em milissegundos de uma PAUSA que ocorrerá! porem esse é um código perigoso que estamos mando nossa aplicação executar, teremos então que tratar as exceções que poderão ocorrer, ficando assim:


int FPS = 30; //TAXA DE ATUALIZAÇÃO DA TELA
while(true){
  try{
    Thread.sleep(1000/FPS);
  }catch(){
    System.out.println("Erro na Thread!"); 
    //MENSAGEM A SER EXIBIDA NO CONSOLE CASO OCORRA ALGUM ERRO
  }
}


Outro detalhe importante na construção de games é, ao mandarmos desenhar algum objeto na tela, como um texto, imagem, forma geométrica, etc, devido ao game loop ficar atualizando a tela o tempo inteiro, dará uma sensação de leg, porque será desenhado na tela elemento a elemento, então qual seria uma solução para esse probleminha?
O Image Buffering, iremos criar um BufferedImage (buffer de imagem)!!!, como é que isso funciona?
Bem é o seguinte... não iremos mais desenhar elementos na tela, ao invés disso iremos desenhar os elementos no buffer, e por fim desenhar o que está no buffer na tela de uma vez só!

então ai segue o corpo do nosso game totalmente comentado:


import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
//A CLASSE GAME HERDA AS FUNCIONALIDADES DE JFRAME
public class Game extends JFrame {

 BufferedImage backBuffer; //ESSE É O NOSSO BUFFER
 int FPS = 30;    //ESSA É A TAXA DE ATUALIZAÇÃO DA TELA
 int janelaW = 500;   //LARGURA DA TELA
 int janelaH = 500;   //ALTURA DA TELA

 //NO NOSSO METODO ATUALIZAR VAMOS CHAMAR OS METODOS
 //QUE SERÃO EXECUTADOS O TEMPO INTEIRO...
 public void atualizar() {

 }

 //NESSE MÉTODO VAMOS DESENHAR
 //FORMAS GEOMETRICAS, IMAGENS E TEXTOS NA TELA E ETC...
 public void desenharGraficos() {
  Graphics g = getGraphics();//COM g IREMOS DESENHAR O QUE ESTÁ NO BUFFER NA TELA
  Graphics bbg = backBuffer.getGraphics();//COM bbg IREMOS DESENHAR NO NOSSO BUFFER
  
  //AQUI ESTAMOS DESENHANDO O BUFFER NA TELA,
  //NAS COORDENADAS X:0 e Y:0
  g.drawImage(backBuffer, 0, 0, this);
 }
 //ESSE É O NOSSO MÉTODO INICIALIZAR
 //AQUI VAMOS INICIALIZAR ALGUMAS CONFIGURAÇÃO DO frame E OUTRAS CONFIGURAÇÕES
 public void inicializar() {
  setTitle("Titulo do Jogo!");//SETANDO O TITULO DA JANELA
  setSize(janelaW, janelaH);//DEFINIDO AS DIMENSÕES DA JANELA
  setResizable(false);//TIRANDO A PERMISSÃO DO USUÁRIO REDIMENSIONAR A JANELA
  setDefaultCloseOperation(EXIT_ON_CLOSE);//QUANDO FECHARMOS O frame A APLICAÇÃO PARA DE EXECUTAR
  setLayout(null);//COM ISSO PODEREMOS DEFINIAR COORDENADA E DIMESÕES DE ELMENTOS DE FORMULARIO NO NOSSO FRAME
  setVisible(true);//MUDANDO A VISIBILIDADE DO frame PARA TRUE, ASSIM ELE APARECERÁ
  backBuffer = new BufferedImage(janelaW, janelaH, BufferedImage.TYPE_INT_RGB);//CRIANDO O NOSSO BUFFER DE IMAGEM
 }
 //AQUI É O NOSSO MÉTODO RUN()
 //NELE TEMOS O NOSSO GAME LOOP (UM LOOP INFINITO)
 public void run() {
  inicializar();//AQUI CHAMAMOS O METODO INICIALIZAR SOMENTE UMA VEZ, POIS ELE ESTÁ FORA DO NOSSO LOOP
  while (true) {//AQUI É O NOSSO LOOP INFINITO
   atualizar();//CHAMAMOS O METODO ATUALIZAR O TEMPO INTEIRO
   desenharGraficos();//ATUALIZAREMOS O GRÁFICO QUE APARECE NA TELA O TEMPO INTEIRO
    try {
     Thread.sleep(1000/FPS); //TAXA DE ATUALIZAÇÃO NA TELA, FUNCIONA COMO UM DELAY
    } catch (Exception e) {
     System.out.println("Thread interrompida!");
    }
  }
 }
 //AQUI É O NOSSO MÉTODO PRINCIPAL
 public static void main(String[] args) {
  Game game = new Game();//CRIAMOS UM OBJETO A PARTIR DESSA PROPRIA CLASSE
  game.run();//CHAMAMOS O METODO RUN(), O MÉTODO RUN() EXECUTA O INICIALIZAR(), ATUALIZAR() E DESENHARGRAFICOS()
 }
 //-----------------------------------------------------------------------------
}// FIM DO CÓDIGO FONTE

Outro pequeno detalhe importante...
Como vamos desenvolver Games 2D, estaremos trabalhando dentro de um plano cartesiano... pra quem não sabe o plano cartesiano foi criado por René Descartes e consiste em em dois eixos perpendiculares um X e outro Y....

porem ....... aqui vai funcionar de uma maneira um pouquinho diferente....


É assim que vamos nos locomover dentro desse plano bidimensional !!!
Então é isso pessoal! continuem no próximo Tutor...

\_(^_^)_/ Comentários em baixo \_(^_^)_/
Comentários
2 Comentários

2 comentários:

Anônimo disse... Best Blogger Tips

Excelente!

Gostei dos gráficos, são bem fáceis de entender.

rinitiwork disse... Best Blogger Tips

cara, muito bom, passei mto tempo procurando uma explicação assim, parabéns pelo conteúdo

Postar um comentário