J2ME Prof. Marcos R Macedo
GAMES
Introdução MIDP 1.0 x MIDP 2.0 GAME API MIDP 2.0 - facilidade de desenvolvimento ; - tamanho da aplicação ; - performance ; - internacionalização ; - algoritmos matemáticos prontos e - padronização. Considerações - display dos dispositivos ; - suporte de cor e áudio (som) ; - tamanho (200K 500K) ; - latência de rede e - billing
Ciclo de Desenvolvimento
Processo
Processo Detalhado Concepção - Desenvolvimento de uma idéia Pré-Produção - Storyboard Produção - 2D to 3D (VRML), Arte Final, Trailer, Avatares Pós-Produção - Deploy, Música e Som, Efeitos Visuais
Storyboard
Elaboração de Imagens 2D / 3D
Avatares
Avatares (cont.)
Efeitos Visuais (Imagens, Ações, Sons)
Algoritmos Aplicados à Jogos Colisão - Objetos / 2D / 3D / Polígonos Renderização - Filmes, Texturas, Sombras, Visões Dimensionais, Movimentos Remotos.. Recursão - Movimentos, repetições, ações Inteligência Artificial - Redes Neurais, Fuzzy, Base de Conhecimento, Jogabilidade - Standalone, MultiPlayer, Ranking online,
Game API
Diagrama de Classes Game API
Canvas É uma classe para as aplicações que necessitam manipular eventos de baixo nível e realizar chamadas para desenhar no Display. A classe Canvas possui métodos para manipular ações de jogos, eventos de teclas e eventos de ponteiros (se suportado pelo dispositivo). Como outras subclasses de Displayable, a classe Canvas permite que a aplicação registre um listener para comandos. Ao contrário de outras subclasses de Displayable,a classe Canvas precisar ser uma subclasse.
Canvas (cont.)
Estados das teclas
Graphics
GameCanvas É uma classe que estende a classe Canvas adicionando a capacidade de leitura, a qualquer momento, da situação das teclas de jogo; e o recurso de gráfico secundário, evitando que imagens parciais sejam exibidas durante a composição de cada cena do jogo.
GameCanvas - Fluxo
GameCanvas (cont.)
Layer / LayerManager Layer: representa um elemento visual do jogo, contento posição espacial, largura, altura e um atributo indicando se está atualmente visível ou não. LayerManager: gerencia uma sequência de Layers e permite a definição de uma janela de visualização que pode ser movida para implementar o scroll de um jogo (p.ex. clipping).
Layer / LayerManager
Layer / LayerManager (cont.)
Layer / LayerManager (cont.)
TiledLayer Implementa um mapa de tiles retangulares, ou seja, uma matriz de células retangulares, onde cada célula pode ser preenchida com uma pequena imagem (tile). Essa técnica permite que grandes cenas sejam compostas a partir de pequenas imagens. Todos os tiles são armazenados em uma única imagem (TileSet). Cada célula recebe um índice do tile correspondente.
TiledLayer (cont.)
TiledLayer (cont.)
Sprite Implementa uma sequênica de imagens (frames) que, quando exibidas em uma certa ordem, produzem uma animação. Todos os possíveis frames devem ser passados em uma única imagem, no entanto, algumas transformações, como espelhamento e rotação, podem ser aplicadas sobre eles, expandindo as possibilidades de exibição.
Sprite (cont.)
Exemplo
Exemplo (cont.)
Exemplo: Step by Step 1 package j2me ; import javax.microedition.midlet.midlet; import javax.microedition.lcdui.display; public class GameMIDlet extends MIDlet { MyGameCanvas gcanvas; public GameMIDlet() { gcanvas = new MyGameCanvas(); public void startapp() { Display display = Display.getDisplay(this); gcanvas.start(); display.setcurrent(gcanvas); public void pauseapp() { public void destroyapp(boolean unconditional) {
Exemplo: Step by Step 2 package j2me ; import java.util.timertask; public class Clock extends TimerTask { int timeleft; public Clock(int maxtime) { timeleft = maxtime; public void run() { timeleft--; public int gettimeleft() { return this.timeleft;
Exemplo: Step by Step 3 package j2me ; import java.util.random; import javax.microedition.lcdui.image; import javax.microedition.lcdui.game.sprite; import javax.microedition.lcdui.game.layermanager; public class CarSprite implements Runnable { public CarSprite(MyGameCanvas parent) { this.parent = parent; this.manager = parent.getmanager(); public void start() { try { carimage = Image.createImage("/j2me/car.png"); catch(exception e) { System.err.println(e); return; runner = new Thread(this); runner.start();
Exemplo: Step by Step 4 public void run() { try { while(true) { randomcar(); Thread.currentThread().sleep(500); catch(exception e) { System.err.println(e);
Exemplo: Step by Step 5 private void randomcar() { if(currentcars == MAX_CARS) return; carsprite = new Sprite(carImage, 10, 10); int randomcarx = parent.getrandom().nextint(parent.game_width); int randomcary = (parent.base parent.getrandom().nextint(parent.max_height + 1) - carsprite.getheight()); if(randomcarx < parent.game_origin_x) randomcarx = parent.center_x; if(randomcary < (parent.base - parent.max_height)) randomcary = parent.center_y; carsprite.setposition(randomcarx, randomcary); manager.insert(carsprite, 0); currentcars++;
Exemplo: Step by Step 6 private void randomcar() { if(currentcars == MAX_CARS) return; carsprite = new Sprite(carImage, 10, 10); int randomcarx = parent.getrandom().nextint(parent.game_width); int randomcary = (parent.base parent.getrandom().nextint(parent.max_height + 1) - carsprite.getheight()); if(randomcarx < parent.game_origin_x) randomcarx = parent.center_x; if(randomcary < (parent.base - parent.max_height)) randomcary = parent.center_y; carsprite.setposition(randomcarx, randomcary); manager.insert(carsprite, 0); currentcars++;
Exemplo: Step by Step 7 public void checkforcollision() { if(manager.getsize() == 2) return; for(int i = 0; i < (manager.getsize() - 2); i++) { if(parent.getcouplesprite().collideswith( (Sprite)manager.getLayerAt(i), true)) { manager.remove(manager.getlayerat(i)); currentcars--; carshit++;
Exemplo: Step by Step 8 public int getcarshit() { return carshit; private Sprite carsprite; private Image carimage; private int currentcars; private MyGameCanvas parent; private LayerManager manager; private Thread runner; private int carshit; private static final int MAX_CARS = 20;
Exemplo: Step by Step 9 package j2me ; import java.util.timer; import java.util.random; import javax.microedition.lcdui.image; import javax.microedition.lcdui.graphics; import javax.microedition.lcdui.game.sprite; import javax.microedition.lcdui.game.gamecanvas; import javax.microedition.lcdui.game.tiledlayer; import javax.microedition.lcdui.game.layermanager; import java.io.ioexception; public class MyGameCanvas extends GameCanvas implements Runnable { public MyGameCanvas() { super(true);
Exemplo: Step by Step 10 public void start() { try { coupleimg = Image.createImage("/j2me/couple2.png"); couplex = CENTER_X; coupley = BASE; couplesprite = new Sprite(coupleImg, 10, 10); couplesprite.definereferencepixel( couplesprite.getwidth()/2, couplesprite.getheight()); manager = new LayerManager(); manager.append(couplesprite); createbackground(); manager.append(background); carsprite = new CarSprite(this); carsprite.start(); catch(ioexception ioex) { System.err.println(ioex); Thread runner = new Thread(this); runner.start();
Exemplo: Step by Step 11 public void run() { clock = new Clock(30); new Timer().schedule(clock, 0, 1000); while(!stop) { verifygamestate(); checkuserinput(); updategamescreen(getgraphics()); try { Thread.currentThread().sleep(30); catch(exception e) { showgamescore(getgraphics());
Exemplo: Step by Step 12 private void createbackground() throws IOException { backgroundimg = Image.createImage("/j2me/tiledlayer1.png"); background = new TiledLayer(5, 5, backgroundimg, 32, 32); int[] cells = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ; for (int i = 0; i < cells.length; i++) { int column = i % 5; int row = (i - column)/5; background.setcell(column, row, cells[i]); background.setposition(game_origin_x, GAME_ORIGIN_Y);
Exemplo: Step by Step 13 private void buildgamescreen(graphics g) { g.setcolor(0x000000); g.drawrect(game_origin_x, GAME_ORIGIN_Y, GAME_WIDTH, GAME_HEIGHT); g.drawline(game_origin_x, BASE, GAME_ORIGIN_X + GAME_WIDTH, BASE); g.drawline(game_origin_x, BASE - MAX_HEIGHT, GAME_ORIGIN_X + GAME_WIDTH, BASE - MAX_HEIGHT); showtimeleft(g); private void verifygamestate() { if(clock.gettimeleft() == 0) { stop = true; return; carsprite.checkforcollision();
Exemplo: Step by Step 14 private void checkuserinput() { int keystate = getkeystates(); calculatecouplex(keystate); calculatecoupley(keystate); private void updategamescreen(graphics g) { g.setcolor(0xffffff); g.fillrect(0, 0, getwidth(), getheight()); buildgamescreen(g); couplesprite.nextframe(); couplesprite.setrefpixelposition(couplex, coupley); manager.paint(g, 0, 0); flushgraphics();
Exemplo: Step by Step 15 private void showtimeleft(graphics g) { int timeleft = clock.gettimeleft(); if(timeleft < 6) { if((timeleft % 2) == 0) g.setcolor(0xff0000); else g.setcolor(0x000000); g.drawstring("tempo: " + timeleft + " segundos", 0, 0, 0); g.setcolor(0x000000); private void showgamescore(graphics g) { g.setcolor(0xffffff); g.fillrect(0, CENTER_Y - 20, getwidth(), 40); g.setcolor(0x000000); g.drawstring("você bateu em " + carsprite.getcarshit() + " carros.", CENTER_X, CENTER_Y, Graphics.HCENTER Graphics.BASELINE); flushgraphics();
Exemplo: Step by Step 16 private void calculatecouplex(int keystate) { if((keystate & LEFT_PRESSED)!= 0) { couplex = Math.max( GAME_ORIGIN_X + couplesprite.getwidth()/2, couplex - dx); else if((keystate & RIGHT_PRESSED)!= 0) { couplex = Math.min( GAME_ORIGIN_X + GAME_WIDTH couplesprite.getwidth()/2, couplex + dx);;
Exemplo: Step by Step 17 private void calculatecoupley(int keystate) { if(up) { if((coupley > (BASE - jumpheight + couplesprite.getheight()))) { coupley -= dy; else if(coupley == (BASE - jumpheight + couplesprite.getheight())) { coupley += dy; up = false; else { if(coupley < BASE) { coupley += dy; else if(coupley == BASE) { int hyper = random.nextint(max_height + 1); if(hyper > couplesprite.getheight()) jumpheight = hyper; coupley -= dy; up = true;
Exemplo: Step by Step 18 public Sprite getcouplesprite() { return this.couplesprite; public LayerManager getmanager() { return this.manager; public Random getrandom() { return this.random;
Exemplo: Step by Step 19 public final int CENTER_X = getwidth()/2; public final int CENTER_Y = getheight()/2; public static final int GAME_WIDTH = 160; public static final int GAME_HEIGHT = 160; public final int GAME_ORIGIN_X = (getwidth() - GAME_WIDTH)/2; public final int GAME_ORIGIN_Y = (getheight() - GAME_HEIGHT)/2; public final int SECTION_HEIGHT = 64; public final int BASE = GAME_ORIGIN_Y + GAME_HEIGHT - SECTION_HEIGHT; public final int MAX_HEIGHT = 32; private Image coupleimg; private Sprite couplesprite; private Image backgroundimg; private TiledLayer background; private int couplex; private int coupley;
Exemplo: Step by Step 20 private int dx = 1; private int dy = 1; private boolean up = true; private int jumpheight = MAX_HEIGHT; public Random random = new Random(); private LayerManager manager; private CarSprite carsprite; private Clock clock; private boolean stop = false;
Exemplos de Jogos J2ME
Alguns links interessantes
55 J2ME GAME