Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

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 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.
187 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.

×