×
Namespaces

Variants
Actions
Revision as of 01:30, 16 August 2013 by hamishwillee (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Detecção de colisão em Java ME

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

Testado com
Aparelho(s): Nokia N95 8GB

Compatibilidade
Plataforma(s):
S60 3rd Edition FP1

Artigo
Tradução:
Por ivocalado
Última alteração feita por hamishwillee em 16 Aug 2013

Contents

Introdução

Este trecho de código mostra como implementar a lógica básica para detecção de colisões que é útil, por exemplo, em jogos simples. Neste exemplo, cinco blocos são desenhados na tela e então são adicionados movimentos a eles (usando os métodos MyCanvas.startBouncing() e MyCanvas.run()). Colisões com as paredes e outros blocos são detectados (usando o método MyCanvas.paint()).

Uma outra possibilidade para implementar detecção de colisões é usando a API MIDP 2.0 Game e especificamente o método javax.microedition.lcdui.game.Sprite.collidesWith().

Código fonte: Block.java

import javax.microedition.lcdui.Graphics;
 
/**
* Representa um blogo
*/

public class Block {
public static final int WIDTH = 10;
public static final int HEIGHT = 10;
public static final int MAX_SPEED = 3;
 
private int[] color = new int[3]; // 3 componentes RGB
private int[] position = new int[2]; // Componentes X e Y
private int[] speed = new int[2]; // Componentes X e Y
 
public Block(int colorR, int colorG, int colorB,
int posX, int posY,
int speedX, int speedY) {
color[0] = colorR;
color[1] = colorG;
color[2] = colorB;
position[0] = posX;
position[1] = posY;
speed[0] = speedX;
speed[1] = speedY;
}
 
public int[] getPosition() {
return position;
}
 
/**
* Arremete o bloco na direção X
*/

public void bounceX() {
speed[0] = -speed[0];
}
 
/**
* Arremete o bloco na direção Y
*/

public void bounceY() {
speed[1] = -speed[1];
}
 
/**
* Atualiza a posição do bloco
*/

public void move() {
position[0] = position[0] + speed[0];
position[1] = position[1] + speed[1];
}
 
/**
* Determina se blocos se interceptam
* @param b o bloco especificado
* @return true se o bloco especificado e este bloco se interceptam
* false caso contrário.
*/

public boolean intersects(Block b) {
int[] tPos = this.getPosition();
int tw = tPos[0] + WIDTH;
int th = tPos[1] + HEIGHT;
int[] bPos = b.getPosition();
int bw = bPos[0] + WIDTH;
int bh = bPos[1] + HEIGHT;
return (bw > tPos[0] && bh > tPos[1] && tw > bPos[0] && th > bPos[1]);
}
 
/**
* Desenha o bloco utilizando o contexto de graphics especificado
*/

public void draw(Graphics g) {
g.setColor(color[0], color[1], color[2]);
g.fillRect(position[0], position[1], WIDTH, HEIGHT);
}
}

Código fonte: MyCanvas.java

import java.util.Random;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
 
/**
* Representa uma pintura em Canvas. Também contém a thread relacionada ao "bouncer"
*/

public class MyCanvas extends Canvas implements Runnable {
private final int NUMBER_OF_BLOCKS = 5;
 
private Block[] blocks;
private boolean running;
 
public MyCanvas() {
Random rnd = new Random();
int width = getWidth();
int height = getHeight();
 
// Inicializa os blocos (cor, posição e velocidade)
blocks = new Block[NUMBER_OF_BLOCKS];
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
int colorR = rnd.nextInt(256);
int colorG = rnd.nextInt(256);
int colorB = rnd.nextInt(256);
int posX = rnd.nextInt(width);
int posY = rnd.nextInt(height);
int speedX = rnd.nextInt(2 * Block.MAX_SPEED + 1) - Block.MAX_SPEED;
int speedY = rnd.nextInt(2 * Block.MAX_SPEED + 1) - Block.MAX_SPEED;
blocks[i] = new Block(colorR, colorG, colorB,
posX, posY,
speedX, speedY);
}
}
 
/**
* Starts the bouncer thread.
*/

public void startBouncing() {
if (running) {
return;
}
// Vamos jogar
running = true;
Thread bouncerThread = new Thread(this);
bouncerThread.start();
}
 
/**
* Stops the bouncer thread.
*/

public void stopBouncing() {
running = false;
}
 
/**
* From Runnable. The main loop.
*/

public void run() {
while (running) {
// Pinta a tela novamente
repaint();
// Pausa por um tempo
try {
Thread.sleep(50);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
 
/**
* From Canvas. Does the painting.
*/

protected void paint(Graphics g) {
// Desenha fundo
int width = getWidth();
int height = getHeight();
g.setColor(255, 255, 255);
g.fillRect(0, 0, width, height);
 
// Atualiza o estado do bloco e desenha-os
for (int i = 0; i < NUMBER_OF_BLOCKS; i++) {
Block block = blocks[i];
 
// Detecta colisões contra as paredes
int[] blockPos = block.getPosition();
if (blockPos[0] + Block.WIDTH >= width || blockPos[0] < 0) {
block.bounceX();
}
if (blockPos[1] + Block.HEIGHT >= height || blockPos[1] < 0) {
block.bounceY();
}
 
// Move o bloco
block.move();
 
// Detecta colisões contra uns com os outros
for (int j = 0; j < NUMBER_OF_BLOCKS; j++) {
Block otherBlock = blocks[j];
if (j != i && block.intersects(otherBlock)) {
block.bounceX();
block.bounceY();
}
}
 
block.draw(g);
}
}
}

Código fonte: BouncyMIDlet.java

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
 
/**
* The main MIDlet.
*/

public class BouncyMIDlet extends MIDlet implements CommandListener {
private MyCanvas canvas;
private Command exitCommand;
 
/**
* Constructor. Constructs the object and initializes displayables.
*/

public BouncyMIDlet() {
canvas = new MyCanvas();
 
exitCommand = new Command("Exit", Command.EXIT, 0);
canvas.addCommand(exitCommand);
canvas.setCommandListener(this);
}
 
/**
* From MIDlet.
* Called when the MIDlet is started.
*/

public void startApp() {
Display.getDisplay(this).setCurrent(canvas);
canvas.startBouncing();
}
 
// Outros métodos herdados omitidos
// ...
 
/**
* From CommandListener.
* Called by the system to indicate that a command has been invoked on a
* particular displayable.
* @param command the command that was invoked
* @param displayable the displayable where the command was invoked
*/

public void commandAction(Command command, Displayable displayable) {
// Sai da MIDlet
if (command == exitCommand) {
canvas.stopBouncing();
destroyApp(true);
notifyDestroyed();
}
}
}

Pós-condições

Cinco blocos estão se movimentando na tela.

This page was last modified on 16 August 2013, at 01:30.
80 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×