Sei sulla pagina 1di 23

Para instalar o MIDP, descompacte o arquivo, pode ser onde desejar, por exemplo, caso esteja usando Windows:

Unidade:\Arquivos de Programas\Java\j2me\midp2.0fcs

Compilando e Rodando::
Antes de tudo, caso esteja no Windows, crie uma varivel de ambiente com o nome de MIDP_HOME apontando para a pasta do midp, por exemplo: c:\arquiv~1\java\j2me\midp2.0fcs E tambm adicionar varivel PATH o seguinte caminho, por exemplo: c:\arquiv~1\java\j2me\midp2.0fcs\bin Aps isso, para compilar, voc vai ter de informar ao compilador que deseja usar as classes do midp, entao: javac -bootclasspath c:\arquiv~1\java\j2me\midp2.0fcs\classes Arquivo.java Aps isso, voc necessita fazer a verificao prvia do arquivo de classe: preverify -classpath c:\arquiv~1\java\j2me\midp2.0fcs;. -d . Classe Agora para rodar o aplicativo basta: midp -classpath . Classe

Projeto Jogo em Java

Pr-projeto::
Antes de comear a colocar a mo na massa, ou no teclado, interessante fazer um esboo do projeto. Bom, primeiramente interessante pensar nas classes que sero necessrias. Para um jogo de carro, obviamente uma classe Veiculo que contenham os atributos de Veiculo. Como ser feita uma aplicao midlet interessante uma classe para a aplicao. Uma classe Canvas para desenhar os componentes na tela. Uma classe abstrata que contem as informaes mnimas para um objeto grfico do jogo, assim qualquer objeto do jogo seja ele veculo, cenrio ou qualquer outro que aparea graficamente para o jogador, possa herdar essa classe. Agora vamos pensar nessas classes individualmente.

Classe ObjetoJogo: Classe abstrata com as mnimas informaes para que um objeto do jogo seja desenhado na tela. Atributos: Image image: imagem do objeto. px: atual posicao x na tela. py: atual posicao y na tela. comprimento: comprimento do objeto (comprimento da imagem) altura: altura do objeto (altura da imagem). Mtodos: meDesenha(Graphics): Mtodo para desenhar o objeto. mtodos get e set para cada atributo

Classe Veiculo: Classe que representa qualquer veculo do jogo, pode ser carro, caminho, moto, etc. Ela herda ObjetoJogo. Atributos: tipo : para diferenciar veiculos com diferentes caractersticas. velocidade: velocidade ATUAL do carro. velocidadeMaxima: velocidade mxima que o veculo pode atingir. energia: energia do veculo, ou o nmero de batidas suportadas. Mtodos: construtores

mtodos get e set para todos os atributos.

Classe AutoEstradaCanvas Classe mais importante do jogo, nela que esto os objetos do jogo e os atributos para manipula-los. Atributos: carroJogador: objeto Veiculo do Jogador. veiculoInimgo[]: array de objeto Veiculo para inumigos. mapa[]: representao matemtica do mapa. numeroVeiculos: nmero de veiculos do mapa atual. loopCounter: contador de loops Obs: Outros Atributos podem ser acrescentados ao longo do desenvolvimento. Mtodos: construtores carregaImagens(): carrega todas imagens do jogo carregaMapa() desenhaVeiculos(Graphics) andaVeiculos(): altera as posies dos Veiculos. colisaoVeiculos(): verifica se ocorreu alguma coliso entre Veiculos. desenhaInterface(Graphics): desenha interface contendo informaes do jogo. paint(Graphics) run() processaTeclas(): processa entrada do usurio. Obs: Outros Mtodos sero adicionados provavelmente ao longo do desenvolvimento. Aqui apenas est o esboo do mnimo de mtodos para desenvolver o jogo proposto.

Classe AutoEstrada: Classe da aplicao midlet AutoEstrada. Atributos: Display: display onde ser desenhada a aplicao. AutoEstradaCanvas: objeto referenciando a classe AutoEstradaCanvas

Mtodos: startApp() stopApp() pauseApp() destroyApp() exitMIDlet

Aps modelar as classes interessante pensar nas imagens que o jogo ir usar: -Imagens para os carros e outros possveis veculos do jogo. -Imagem de Background. -Imagens de componentes de cenrio. Possiveis imagens:

No caso o formato que ser utilizado o png.

Implementando a Classe ObjetoJogo::


/* arquivo ObjetoJogo.java */ /* Vamos usar as classes Graphics e Image de lcdui. */ import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; public abstract class ObjetoJogo { /* Atributos da classe conforme o planejado */ protected Image image; protected int px; protected int py;

protected int comprimento; protected int altura; /* Mtodo abstrato que toda classe que herdar dever implementar */ public abstract void meDesenha(Graphics g); /* Mtodos get e set para os atributos. */ public int getPx() { return px; } public void setPx(int x) { px = x; } public int getPy() { return py; } public void setPy(int y) { py = y; } public int getComprimento() { return comprimento; } public int getAltura() { return altura; } }

Implementando a Classe Veiculo::


/* arquivo Veiculo.java */ /* Vamos usar as classes Graphics e Image de lcdui. */ import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; public class Veiculo extends ObjetoJogo { /* Atributos da classe */ private int tipo, velocidade, velocidadeMaxima, energia; /* Construtores */ public Veiculo() { tipo = 0; velocidade = 0;

velocidadeMaxima = 0; energia = 0; } public Veiculo(Image i, int t, int x, int y, int veloM, int e) { super.image = i; super.comprimento = image.getWidth(); super.altura = image.getHeight(); super.px = x; super.py = y; tipo = t; velocidade = 0; velocidadeMaxima = veloM; energia = e; } / * Metodos get e set. */ public int getTipo() { return tipo; } Como energia um atributo que normalmente ser incrementado ou decrementado, criamos um mtodo para incremento. Assim ao invs de: veiculo.setEnergia(veiculo.getEnergia()+1); veiculo.setEnergia(veiculo.getEnergia()-1); Pode ser feito: veiculo.incEnergia(1); veiculo.incEnergia(-1); public void incEnergia(int i) { energia+=i; } public void setEnergia(int i) { energia = i; } public int getEnergia() { return energia; } /* incrementa velocidade caso velocida atual + incremento menor ou iqual a velocidadeMaxima */ public void incVelocidade(int x) { if(velocidade+x <= velocidadeMaxima) velocidade+=x; else velocidade = velocidadeMaxima; } public void setVelocidade(int i) {

velocidade = i; } public int getVelocidade() { return velocidade; } public void setVelocidadeMaxima(int i) { velocidadeMaxima = i; } /* Mtodo que deve ser obrigatoriamente implementado, pois toda classe que herda ObjetoJogo deve te-lo. */ public void meDesenha(Graphics g) { g.drawImage(super.image, super.px, super.py, Graphics.TOP | Graphics.LEFT); } }

Implementando a Classe AutoEstrada::


Esta a classe mais simples, nesta esto os mtodos que sero chamados ao carregar e fechar o jogo. Nesta classe um objeto AutoEstradaCanvas criado e relacionado com o Display. /* arquivo AutoEstrada.java */ import javax.microedition.lcdui.*; import javax.microedition.midlet.*; public class AutoEstrada extends MIDlet { private Display display; private AutoEstradaCanvas autoEstradaCanvas; public AutoEstrada() { display = Display.getDisplay(this); autoEstradaCanvas = new AutoEstradaCanvas(); } protected void startApp(){ display.setCurrent(autoEstradaCanvas); } protected void pauseApp(){} protected void destroyApp(boolean unconditional){} public void exitMIDlet(){ destroyApp(false); notifyDestroyed(); }

Implementando a Classe AutoEstradaCanvas::


Agora iremos a implementao da classe AutoEstradaCanvas. Nesta classe ficaro os principais mtodos do jogo. Classe responsvel por desenhar os objetos na tela, receber entrada do usurio pelo teclado, e todo o processamento do jogo. Abaixo est uma pequena parte da classe, os mtodos sero adicionados aos poucos. /* arquivo AutoEstradaCanvas.java */ import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.Font; import javax.microedition.lcdui.game.GameCanvas; import java.io.IOException; public class AutoEstradaCanvas extends GameCanvas implements Runnable { /* nmero atual de loops executados dentro de um segundo */ private int loopCounter; /* nmero de milisegundos que o jogo dorme voluntariamente */ private final static int sleepTime = 30; public AutoEstradaCanvas() { /* constructor GameCanvas(boolean suppressKeyEvents)*/ super(true); new Thread(this).start(); } private void iniciaJogo() { } /* O paint chamar os mtodos para desenhar cada Objeto. */ public void paint(Graphics g) { } Mtodo run obrigatoriamente implementado para toda classe que implementa Runnable. Este mtodo chamar os mtodos que precisam ser executados a cada quadro do jogo. Praticamente todos os mtodos sero executados a cada quadro do jogo, exceto os mtodos para carregar, ou que sero chamados em um evento especfico do jogo, como por exemplo morrer ou vencer! public void run() { try {

while(true) { Thread.sleep(sleepTime); if(loopCounter<sleepTime) loopCounter++; else loopCounter=0; } } } }

Inicializao::
Na inicializao todas as imagens devero ser carregadas e os devidos objetos devero ser instanciados. O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. /* Veiculo controlado pelo jogador */ private Veiculo carroJogador; Posio px de cada coluna ou faixa da pista. Esses valores so obtidos a partir da imagem usada como background. Essas constantes sero usadas para elaborao do mapa, ao invs de colocar a posio px para cada veculo, colocaremos a coluna ou faixa da pista. private final static int col1 = 46, col2 = 82, col3 = 116; bordaEsquerda a posio px da borda esquerda da pista (Obtido pela imagem de background). bordaDireita a posio px da borda direita da pista (Obtido pela imagem de background). private final static int bordaEsquerda = 36, bordaDireita = 143; /* Imagens que devero ser utilizadas no jogo */ private Image carro1, carro2, carro3, carro4, caminhao, placa, back; private boolean pausado;

/* Carrega as imagens do jogo */ private void carregaImagens()

{ try { carro1 = Image.createImage("/imagens/carro1.png"); carro2 = Image.createImage("/imagens/carro2.png"); carro3 = Image.createImage("/imagens/carro3.png"); carro4 = Image.createImage("/imagens/carro4.png"); caminhao = Image.createImage("/imagens/caminhao.png"); placa = Image.createImage("/imagens/placa.png"); back = Image.createImage("/imagens/back.png"); } catch(IOException e) { System.out.println("Erro ao carregar Imagens"); e.printStackTrace(); } } Inicia o jogo. Cria o carro do jogador usando a imagem carro1.png. Zera loopCounter e coloca pausado como false private void iniciaJogo() { carroJogador = new Veiculo(carro1, 0, col2,130, 130, 5); pausado = false; loopCounter=0; }

/* Cdigo que dever ser adicionado dentro do construtor AutoEstradaCanvas() */ carregaImagens(); iniciaJogo();

Mapa::
Mapa nada mais que um representao matemtica do ambiente do jogo. No caso deste jogo, mapa nada mais que as posies dos veculos na auto-estrada. Essas posies no em pixels. Quanto mais longe um veculo est da posio atual no mapa, mais negativa sua posio. Ex: A tela comea no pixel 0. Um veculo est a 2000 pixels de distncia, ento conseqentemente, sua posio py no mapa -2000. Porm apenas a posio py no mapa, no o suficiente para a criao do ambiente do jogo. Alm disso, precisamos da posio px e precisamos distinguir um veculo do outro. Na classe veculo h um atributo tipo. Usaremos ele para isso. Ento nosso array de mapa ficar assim:

{tipo_carro1, px_carro1, py_carro1, tipo_carro2, px_carro2, py_carro2 ... } No comeo do array informaremos quantos veculo o mapa tem. Definindo os tipos dos carros: 1 = carro imagem 1 2 = carro imagem 2 3 = carro imagem 3, porm carro que tenta fechar jogador 4 = caminho. O cdigo abaixo devero ser adicionados dentro da classe AutoEstradaCanvas. /* Vetor de objetos veiculo de inimigos. */ private Veiculo veiculoInimigo[]; /* mapa = numero de veiculos - (tipo, px, py)) */; private int mapa1[]={49,1,col1,60,1,col3,60,1,col2,-40,1,col3,-140,4,col1,-200, 2,col2,-270,2,col2,-500,1,col3, -580, 2,col1,-630, 4,col2,-730, 2,col1,-780,3,col1,-850,2,col1,-930,3,col2,-990,4,col1,-1100, 1,col3,-1200,2,col2,-1300,4,col1,-1400,1,col2,-1490,2,col3,-1600, 3,col1,-1700,3,col3,-1800,2,col2,-1890,1,col1,-1960,4,col3,-2120, 1,col2,-2200,2,col1,-2270,2,col3,-2350,4,col1,-2450,1,col2,-2500, 4,col1,-2650,4,col3,-2650,3,col1,-2750,2,col2,-2830,1,col1,-2900, 3,col1,-3100,3,col3,-3300,3,col1,-3500,1,col3,-3600,2,col2,-3670, 1,col2,-3750,4,col3,-3770,3,col1,-3870,2,col3,-3950,1,col2,-4070, 1,col1,-4140,3,col3,-4220,2,col2,-4300,3,col3,-4390}; private int mapa[]; /* varivel com o numero de veculos de inimigos do mapa atual */ private int numVeiculos; private void setMapa(int m[]) { mapa = m; } Mtodo que carrega o mapa. Pega a posio e os atributos dos veculos dos inimigos e instancia objetos do vetor de veculos de inimigos. O vetor mapa apenas passa a posio px, py, e tipo. Isto para ficar mais simples, porm os outros atributos como velocidade inicial e velocidade mxima tambm poderiam ser informaes obtidas no vetor do mapa. private void carregaMapa() { Image img=null; int x,y; numVeiculos = mapa[0]; veiculoInimigo = new Veiculo[numVeiculos]; for(y=0, x=1; y<numVeiculos; x+=3, y++) { if(mapa[x] == 1) img = carro2; else if(mapa[x] == 2) img = carro3; else if(mapa[x] == 3)

img = carro4; else if(mapa[x] == 4) img = caminhao; veiculoInimigo[y] = new Veiculo(img, mapa[x], mapa[x+1], mapa[x+2], 100 ,3); veiculoInimigo[y].setVelocidade(10); } }

/* Cdigo que dever ser adicionado dentro do mtodo iniciaJogo(). */ setMapa(mapa1); carregaMapa();

Desenhando o Jogo::
Mtodos que "desenham" o jogo no display. O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. Mtodo abaixo no tem mistrio, primeiro desenha o veculo controlado pelo usurio. Depois varre o vetor de veculos do computador, verifica quem esta no espao x,y do display, caso sim, o desenha. private void desenhaVeiculos(Graphics g) { int x; carroJogador.meDesenha(g); for(x=0; x<numVeiculos; x++) { if(veiculoInimigo[x].getPy() +veiculoInimigo[x].getAltura() > 0) veiculoInimigo[x].meDesenha(g); } } Mtodo abaixo desenha um barra contendo informaes sobre o veculo controlado pelo jogador. Neste caso essas informaes so velocidade, posio e energia. private void desenhaInterface(Graphics g) { g.setColor(0,0,0); g.fillRect(0,164,180,20); g.setColor(255,255,255); g.drawString("Vel: " + carroJogador.getVelocidade() + " Pos: "+ getPosicao()+" Ener: "+carroJogador.getEnergia(), 50,165, Graphics.TOP | Graphics.LEFT); } O mtodo getPosicao() utilizado acima para pegar a posio atual do carro do jogador o seguinte: private int getPosicao() {

int carros = mapa[0]; int p=0; for(int x=0; x<numVeiculos; x++) { if(carroJogador.getPy() < veiculoInimigo[x].getPy()) p++; } return numVeiculos-p+1; } O Mtodo paint desenha o a imagem de background e depois os veculos e depois a interface. public void paint(Graphics g) { if(!pausado) { g.drawImage(back,0,0,Graphics.TOP | Graphics.LEFT); desenhaVeiculos(g); desenhaInterface(g); } } E dentro do while(true) do mtodo run, antes da linha if(loopCounter < sleepTime) Coloque o seguinte cdigo: repaint();

Movendo os Veculos::
No jogo a cmera fica travada no veculo controlado pelo jogador. So os veculos controlados pelo computador que na verdade se movimentam. Nesta parte um mtodo faz todo o movimento dos veculos dos inimigos, desde mover para frente, como mover para o lado. J o veculo do jogador se move conforme a entrada atravs do teclado. Ele pode mover para direita e para esquerda, acelerar e brecar. O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. private void andaVeiculos() { /* pega os atributos do carro do jogador */ int x; int j_px, j_c, i_px, i_c, i_py, i_a; j_px = carroJogador.getPx(); j_c = carroJogador.getComprimento(); for(x=0; x<numVeiculos; x++) { /* pega os atributos do carro do inimigo */ i_px = veiculoInimigo[x].getPx(); i_c = veiculoInimigo[x].getComprimento(); i_py = veiculoInimigo[x].getPy(); i_a = veiculoInimigo[x].getAltura();

Move o veculo do inimigo para frente. Esse movimento obtido pela diferena de velocidade entre o veculo do jogador e o veculo do inimigo. Como essa diferena vai ser passada para pixels, o valor no pode ser muito grande, no caso dividimos esse valor por 5. Sendo assim, qualquer tipo de movimentao dentro do jogo tambm tem quer ser dividido por 5, para manter a proporo. veiculoInimigo[x].incVelocidade(1); veiculoInimigo[x].setPy(veiculoInimigo[x].getPy() + ((carroJogador.getVelocidade() veiculoInimigo[x].getVelocidade())/5)); Faz com que o veculo inimigo desvie do veculo do jogador caso ele esteja atrs do veculo do jogador. Isso feito para que caso o veculo inimigo esteja mais rpido que o do jogador, ele desvie para ultrapassar. Mas isso se der tempo de desviar. Caso jogador ultrapasse, entre na frente e de uma freiada, obviamente o inimigo vai colidir com o jogador. if(veiculoInimigo[x].getPy() > carroJogador.getPy()) { if((i_px <= j_px && i_px+i_c > j_px) || (i_px >= j_px && i_px+i_c <= j_px+j_c)) { if(j_px-j_c > bordaEsquerda) veiculoInimigo[x].setPx(veiculoInimigo[x].getPx() - 3); else veiculoInimigo[x].setPx(veiculoInimigo[x].getPx() + 3); } else if(i_px+i_c >= j_px+j_c && i_px < j_px+j_c) { if(j_px+j_c+j_c < bordaDireita) veiculoInimigo[x].setPx(veiculoInimigo[x].getPx() + 3); else veiculoInimigo[x].setPx(veiculoInimigo[x].getPx() - 3); } } Faz com que o veculo inimigo que tem o tipo == 3, feche o carro do jogador. Ele fica tentando fechar at que o veculo do jogador chegue a uma certa distncia dele. if(veiculoInimigo[x].getTipo() == 3) { if(i_py+i_a > 0 && i_py < 60) { if(i_px < j_px) { if(i_px+3 > j_px) veiculoInimigo[x].setPx(j_px); else veiculoInimigo[x].setPx(i_px + 3); } else if(i_px > j_px) { if(i_px -3 < j_px) veiculoInimigo[x].setPx(j_px); else veiculoInimigo[x].setPx(i_px - 3); } }

} } } Mtodo que processa a entrada do usurio por meio do teclado. Faz o obvio, apertou tecla right, move o veculo para direita, apertou tecla left, move para esquerda, isso fazendo as devidas verificaes para que o carro no saia da a pista. Apertou up, acelera. O loopCounter usado para diminuir a acelerao, como o jogo tem um frame rate, caso no use o loopCounter o carro aceleraria o equivalente de vezes ao frame rate. Assim usamos o modulo do loopCounter para diminuir essa aceleraao. Apertou a tecla down ele freia. Lembrando que essas teclas variam por dispositivos, podem ser teclas de seta, como teclas nmericas. Porm todo dispositivo ter uma tecla que representa LEFT,RIGHT,DOWN,UP,FIRE, etc. O operador utilizado dentro dos "ifs" & mesmo, no confunda com &&. O operador && equivalente ao AND lgico, mas para operandos booleanos. O operador & para bits. Um exemplo, voc tem um byte b1 (11101010), e um segundo byte b2 (00101001). Ento: b1 & b2 = (00101000), no resultado os bits s sero 1 caso o mesmo bit seja 1 tanto em b1 como b2. private void processaTeclas() { int keyStates = getKeyStates(); if((keyStates & UP_PRESSED)!=0) carroJogador.incVelocidade(1); else { if(carroJogador.getVelocidade() >= 1) { if(loopCounter % 3 == 0) carroJogador.incVelocidade(-1); } } if((keyStates & DOWN_PRESSED)!=0) { if(carroJogador.getVelocidade() >=5) carroJogador.incVelocidade(-1); } if((keyStates & LEFT_PRESSED)!=0) { int px = carroJogador.getPx(); if(px 3 >= MARGEM_ESQUERDA) { carroJogador.setPx(px-3); } } if((keyStates & RIGHT_PRESSED)!=0) { int px = carroJogador.getPx(); if(px + 3 <= MARGEM_DIREITA) { carroJogador.setPx(px+3);

} } } E dentro do while(true) do mtodo run, depois da linha Thread.sleep(sleepTime); Coloque o cdigo: processaTeclas(); if(!pausado) { andaVeiculos() }

Coliso::
O sistema de coliso responsvel por detectar colises entre objetos na tela. No caso do Auto-Estrada, ele apenas verifica coliso entre o carro controlado pelo jogador e os carros inimigos. Isto feito comparando a posicao px, py, comprimento e altura do carro controlado pelo jogador, com os mesmos atributos de todos os carros inimigos. Se um carro estiver dentro do outro, quer dizer que ocorreu uma coliso. A imagem abaixo mostra alguma das possibilidades de coliso:

O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. /* Mtodo para verificar se ocorreu coliso, retorna true caso sim, false caso nao. */ private boolean colisaoVeiculos() { int j_px = carroJogador.getPx(), j_py = carroJogador.getPy(), j_c = carroJogador.getComprimento(),

j_a = carroJogador.getAltura(); int i_px, i_py, i_c, i_a; for(int x=0;x<numVeiculos;x++) { i_px = veiculoInimigo[x].getPx(); i_py = veiculoInimigo[x].getPy(); i_c = veiculoInimigo[x].getComprimento(); i_a = veiculoInimigo[x].getAltura(); Os "ifs" abaixo fazem a comparao entre as posies das imagens dos veculos para saber se ocorreu coliso. A lgica do "if" a mesma mostrada na imagem acima. Repare que na imagem existem 16 possibilidades de coliso entre as imagens dos veculos. Existem dois "ifs", cada um com 4 condies, sendo assim: 4x4 = 16 if(!(i_py > -100 && i_py < 280)) continue; if((j_px <= i_px && j_px+j_c > i_px) || (j_px < i_px+i_c && j_px+j_c >= i_px+i_c) || (j_px >= i_px && j_px+j_c <= i_px+i_c) || (i_px >= j_px && i_px+i_c <= j_px+j_c)) { if((j_py < i_py+i_a && j_py > i_py) || (j_py+j_a > i_py && j_py+j_a < i_py+i_a) || (j_py >= i_py && j_py+j_a <= i_py+i_a) || (i_py >= j_py && i_py+i_a <= j_py+j_a)) return true; } } return false; }

O cdigo abaixo demonstra o sistema de coliso sendo utilizado, verificando se ocorreu coliso. Caso tenha ocorrido uma coliso, ele volta o veculo para a posio anterior a coliso, diminui a velocidade do carro do jogador para 60 e decrementa a energia do carro do jogador. Esse cdigo deve ser usado no mtodo andaVeiculos(). A linha: veiculoInimigo[x].setPy(veiculoInimigo[x].getPy() + ((carroJogador.getVelocidade() veiculoInimigo[x].getVelocidade())/5)); Deve ser substituida por: py_ant = veiculoInimigo[x].getPy(); veiculoInimigo[x].setPy(veiculoInimigo[x].getPy() + ((carroJogador.getVelocidade() veiculoInimigo[x].getVelocidade())/5)); if(colisaoVeiculos()) { veiculoInimigo[x].setPy(py_ant); carroJogador.setVelocidade(60); carroJogador.incEnergia(-1); } O cdigo abaixo demonstra o sistema de coliso sendo utilizado na hora de mover o carro do jogador horizontalmente. Funciona da mesma maneira explicada acima. O py_ant+10 e py_ant-

10 para evitar que ocorra mais de uma coliso em uma batida. Pois se o jogador est com a tecla LEFT pressionada por exemplo, o carro colide, volta para posio anterior a coliso, a tecla continua pressionada, ele colide denovo. Como esse processamento muito rpido, vo ser vrias colises em uma batida. Devido a isso, a cada coliso afastamos os dois carros que colidiram. O cdigo abaixo deve ser substituido dentro do mtodo processaTeclas(). if((keyStates & LEFT_PRESSED)!=0) { int px_ant = carroJogador.getPx(); if(px_ant - 3 >= MARGEM_ESQUERDA) { carroJogador.setPx(carroJogador.getPx()-3); if(colisaoVeiculos()) { carroJogador.setPx(px_ant+10); carroJogador.setVelocidade(60); carroJogador.incEnergia(-1); } } } if((keyStates & RIGHT_PRESSED)!=0) { int px_ant = carroJogador.getPx(); if(px_ant + 3 <= MARGEM_DIREITA) { carroJogador.setPx(px_ant+3); if(colisaoVeiculos()) { carroJogador.setPx(px_ant-10); carroJogador.setVelocidade(60); carroJogador.incEnergia(-1); } } }

Rolagem de Mapa::
Rolagem de Mapa ou Map Scrolling a tcnica utilizada para dar a impresso de que um jogo tem um mapa contnuo. Isto feito movimentando o fundo do jogo e seus componentes, conforme os movimentos do personagem. No caso do Auto-Estrada, ser o cho (linhas do cho se movendo) e as placas na beira da estrada. Na verdade o Auto-Estrada no tem um mapa, isso porque as imagens vo ficar se repetindo. Porm a velocidade com que as placas e as linhas no cho vo se mover, ser proporcional a velocidade do carro. Isso dar a iluso de que existe um mapa, de que a estrada continua. O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. /* posicao y das linhas do cho */ private final static int linhas[]={150,100,50,0,-50,-100,-150};

/* posicao y da placa na beira da estrada */ private int placapy = 90; /* mtodo simples para desenhar as linhas, sao desenhadas duas linhas dividindo a estrada em 3. */ private void desenhaLinhas(Graphics g) { g.setColor(255,255,255); for(int x=0; x<linhas.length;x++) { g.fillRect(34+bordaEsquerda,linhas[x],3,20); g.fillRect(69+bordaEsquerda,linhas[x],3,20); } } Mtodo para fazer o movimento das linhas. Repare que ele divide por 5 a velocidade. Isto j foi mencionado anteriormete, todos os mtodos que usam velocidade fazem a mesma diviso para manter a proporo. No final linhas-=300, porque a primeira linha comea no 150 e ultima acaba no -150. Ento quando a primeira sai do espao da tela, subtraido 300 e ela passa a ocupar o espao da ultima, que agora oculpa o da penultima e assim por diante. Essa faixa de valores pode ser menor! private void andaLinhas() { int vel = carroJogador.getVelocidade(); for(int x=0; x<linhas.length;x++) { if(vel > 5) linhas[x]+=vel/5; else if(vel != 0) linhas[x]++; if(linhas[x] > 180 ) linhas[x]-=300; } } /* Funciona da mesma maneira que andaLinhas(). */ private void andaPlacas() { int vel = carroJogador.getVelocidade(); if(vel > 5) placapy+=vel/5; else if(vel != 0) placapy++; if(placapy > 180 ) placapy-=210; } /* Funciona da mesma maneira que desenhaPlacas(). */ private void desenhaPlacas(Graphics g) { g.drawImage(placa, 5, placapy, Graphics.TOP | Graphics.LEFT); g.drawImage(placa, 150, placapy, Graphics.TOP | Graphics.LEFT); }

/* As duas chamadas de mtodo abaixo devem ser adicionadas ao mtodo paint() antes da linha: desenhaVeiculos(g); */ desenhaLinhas(g); desenhaPlacas(g); /* As duas chamadas de mtodo abaixo devem ser adicionadas ao mtodo run() antes da linha: andaVeiculos(); */ andaLinhas(); andaPlacas();

Semforo::
Para que o jogador se ambiente com o jogo, tenha tempo de observar a tela antes do jogo comear, no precise carregar o jogo j acelerando, vamos implementar um semforo. Ser bem simples. Quando o jogo carregar o semforo estar apagado, depois acender a primeira luz vermelha, depois a segunda, e depois acender a luz verde e a corrida comea. O cdigo abaixo deve ser inserido dentro da classe AutoEstradaCanvas. /* variavel que armazena o atual estado do semforo */ private int semaforo; /* 0 = apagado 1 = primeiro vermelho 2 = segundo vermelho 3 = verde */ /* Faz a mudana do estado semforo caso ele no esteja verde */ private void processaSemaforo() { if(loopCounter == sleepTime && semaforo != 3) semaforo++; } O cdigo abaixo desenha o semforo na tela. O cdigo bem simples, verifica o estado do semforo para escolher as cores das bolinhas que representam as luzes. O cdigo dever ser inserido dentro do mtodo desenhaInterface() depois da linha: g.drawString("Vel: " + carroJogador.getVelocidade() + " Pos: "+ getPosicao()+" Ener: "+carroJogador.getEnergia(), 50,165, Graphics.TOP | Graphics.LEFT);

int bola1 = 0x960000; /* RGB 150,0,0 */ int bola2 = 0x960000; int bola3 = 0x009600; /* RGB 0,150,0 */ if(semaforo > 0) bola1 = 0xFF0000; if(semaforo > 1)

bola2 = 0xFF0000; if(semaforo > 2) bola3 = 0x00FF00; g.setColor(bola1); g.fillArc(2,167,8,8,0,360); g.setColor(bola2); g.fillArc(12,167,8,8,0,360); g.setColor(bola3); g.fillArc(22,167,8,8,0,360);

O cdigo abaixo demonstra como deve ser o cdigo dentro do while(true) do mtodo run() aps a implementao do semforo: Thread.sleep(sleepTime); if(semaforo == 3) { processaTeclas(); if(!pausado) { andaLinhas(); andaPlacas(); andaVeiculos(); } } else processaSemaforo(); repaint(); if(loopCounter<sleepTime) loopCounter++; else loopCounter=0;

Aps tudo isso, no esquece de adicionar: semaforo = 0; Dentro do mtodo iniciaJogo()

Venceu ou Morreu::
Um jogo necessita ter um objetivo e um fim. No Auto-Estrada o objetivo chegar primeira posio. O fim conquistar o objetivo ou morrer antes. Ser implementado dentro do mtodo paint() o cdigo necessrio para imprimir a devida mensagem quando uma das condies for satisfeita. O novo cdigo do mtodo paint() deve ser o seguinte:

public void paint(Graphics g) { if(!pausado) { g.drawImage(back,0,0, Graphics.TOP | Graphics.LEFT); desenhaLinhas(g); desenhaPlacas(g); desenhaVeiculos(g); desenhaInterface(g); } Posicao == 1 quer dizer que o jogador chegou a primeira posio, ento venceu. Ento o jogo pausando e a mensagem dizendo que ele vendeu impressa. Ele precisa apertar a tecla FIRE ou tecla 5, isso varia com dispositivo, para jogar novamente. if(getPosicao() == 1) { pausado = true; g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE)); g.setColor(255,0,0); g.drawString("VOC VENCEU!", 40,70, Graphics.TOP | Graphics.LEFT); g.drawString("PRESSIONE FIRE (5)", 20,90, Graphics.TOP | Graphics.LEFT); } Se enegia == 0 quer dizer que o jogador morreu. Ento o jogo pausando e a mensagem dizendo que ele morreu ou perdeu impressa. Ele precisa apertar a tecla FIRE ou tecla 5, isso varia com dispositivo, para jogar novamente. else if(carroJogador.getEnergia() == 0) { pausado = true; g.setFont(Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE)); g.setColor(255,0,0); g.drawString("GAME OVER", 40,70, Graphics.TOP | Graphics.LEFT); g.drawString("PRESSIONE FIRE (5)", 20,90, Graphics.TOP | Graphics.LEFT); } }

Para que o usurio possa jogar novamente aps ter vencido ou morrido, o seguinte cdigo deve ser adicionado ao mtodo processaTeclas() para que o jogo seja reiniciado. if((keyStates & FIRE_PRESSED) != 0) { if(pausado) { pausado = false; iniciaJogo(); } }

Concluso::
Aps ter seguido todos os passos anteriores, ter um cdigo parecido com este: AutoEstrada-v1.0-src.zip

Possveis melhorias:
O objetivo deste artigo foi desenvolver um jogo simples, porm que demostrasse alguns conceitos de desenvolvimento de jogos. Algumas possveis melhorias: :: Melhoria no algoritmo de inteligncia dos inimigos: isso pois o algoritmo no funciona totalmente, quanto a parte de fechar o veculo do jogador, pode-se desenvolver um algoritmo mais elaborado. Tanto a parte de fechar o veculo do jogador, como desviar para ultrapassar, no considera os outros veculos inimigos. Ento possvel que um veculo inimigo passe por cima do outro tentado manobrar. ::Sistema de Coliso: o sistema de coliso no diferencia totalmente as colises em lateral, frontal superior e inferior. Quando ocorre uma coliso frontal, o carro do jogador perde velocidade e energia, porm se for o inimigo que bate no carro do jogador por trs, o carro perde velocidade e continua batendo. Isso faz com que o jogador as vezes morra, com apenas uma coliso. Diferenciando as colises, ser possvel tratar este problema.

Novos possveis recursos:


::Mapa: o Auto-Estrada no tem um mapa real, apenas fica se repetindo o cenrio. Pode-se criar um mapa real, armazenando as posies de componentes de cenrio no array do mapa. ::Itens: pode-se criar itens para o jogo. Itens que o jogador pode pegar, como energia, gasolina e turbo por exemplo. A partir disto, a necessidade de implementar combustvel e turbo. Pode haver tambm itens que se o jogador encostar, sofre alguma penalidade. Como exemplo uma possa de leo ou um baraco por exemplo. Essas informaes ficariam contidas no array de mapa. ::Novas Fases ::Novos Veculos

Potrebbero piacerti anche