Reflexão de imagens em Java ME

20 dezembro 2009 0 comentários
Este post mostra como criar um efeito de reflexão a partir de uma simples imagem.

Através do método createReflectedImage, da Classe que será mostrada abaixo, podemos fazer a reflexão da imagem passando 3 argumentos:

- A imagem original a ser refletida
- A cor de fundo (usado para imagens transparentes)
- A altura do efeito de reflexão


É necessário criar uma imagem mutável que irá realizar o efeito resultante:

int w = image.getWidth();

int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Foi armazenado a largura e altura da imagem original em 2 variáveis int, e em seguida, criou-se a imagem mutável com a mesma largura, mas com uma altura igual a h (imagem original) mais a altura da reflexão especificada.

Para fazer a cópia da imagem original é necessário usar o objeto Graphics da imagem mutável, preenchendo a imagem com a cor de fundo. Então é possível desenhar a imagem original na parte superior fazendo a mutação da imagem.

Para criar o efeito de reflexão em cada linha horizontal da parte da imagem refletida, toma-se a coordenada vertical correspondente da imagem original, então obtem-se os dados RGBA da linha horizontal correspondente à imagem original para calcular o alfa a ser aplicado a esta linha, e então aplicá-lo a cada elemento da matriz de dados RGB para elaborar os dados RGB da imagem refletida, utilizando seu objeto Graphics. Veja:

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
Obs: O array rgba [] contém a linha atual dos dados de pixel, e será atualizada somente quando necessário. Desta forma a imagem é mutada no decorrer da coordenada y. Para usar o método basta criar a imagem original a ser refletida e chamar ReflectedImage.create(x, y, z), passando a imagem original como argumento, juntamente com a cor de fundo e a altura do efeito de reflexão. ReflectedImage.java
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class ReflectedImage
{
public static Image create(Image image, int bgColor, int reflectionHeight)
{
int w = image.getWidth();
int h = image.getHeight();

Image reflectedImage = Image.createImage(w, h + reflectionHeight);

Graphics g = reflectedImage.getGraphics();

g.setColor(bgColor);
g.fillRect(0, 0, w, h + reflectionHeight);

g.drawImage(image, 0, 0, Graphics.TOP | Graphics.LEFT);

int[] rgba = new int[w];
int currentY = -1;

for(int i = 0; i < reflectionHeight; i++)
{
int y = (h - 1) - (i * h / reflectionHeight);

if(y != currentY)
image.getRGB(rgba, 0, w, 0, y, w, 1);

int alpha = 0xff - (i * 0xff / reflectionHeight);

for(int j = 0; j < w; j++)
{
int origAlpha = (rgba[j] >> 24);
int newAlpha = (alpha & origAlpha) * alpha / 0xff;

rgba[j] = (rgba[j] & 0x00ffffff);
rgba[j] = (rgba[j] | (newAlpha << 24));
}

g.drawRGB(rgba, 0, w, 0, h + i, w, 1, true);
}
return reflectedImage;
}
}
MIDletReflexao.java
import java.io.IOException;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class MIDletReflexao extends MIDlet {

Display display;
private Form form;
private ImageItem imageItem;
private Image image;

public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(getForm());
}

public Form getForm() {
if (form == null) {
form = new Form("Form", new Item[] { getImage() });
}
return form;
}

public ImageItem getImage() {
if (imageItem == null) {
try {
image = Image.createImage("/img.png");
} catch (IOException ex) {
ex.printStackTrace();
}
Image reflectedImage = ReflectedImage.create(image, 0xffffff, 64);
image=reflectedImage;
imageItem = new ImageItem("Reflexão", image, ImageItem.LAYOUT_DEFAULT, "Imagem perdida");
}
return (ImageItem) imageItem;
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}
}
Fonte: Classe Original: ReflectedImage.java http://wiki.forum.nokia.com/index.php

Google Phone: O SmartPhone da vez

13 dezembro 2009 0 comentários
O boato de que o Google lançaria o seu próprio smartphone para competir com o iPhone está ganhando força. Pelo Twitter, alguns funcionários disseram já ter o aparelho em mãos. As informações são de que ele seria tão fino quanto o concorrente da Apple, fabricado pela HTC e equipado com o sistema Android 2.1.

"Nós tivemos fogos de artifícios e todos nós ganhamos o novo Google Phone. Ele é lindo", twittou a a gerente de produtos open source da empresa, Leslie Hawthorn.

"O novo Google Phone tem o hardware da HTC e roda Android 2.1, que tem novos recursos visuais como planos de fundo animados". Jason Howell, repórter do site de tecnologia CNet.

Quase todos os funcionários do Google, diz ele, receberam o smartphone de presente, desbloqueado. O lançamento ficaria para o fim de janeiro de 2010, porém a empresa ainda não fez um anúncio oficial do lançamento do telefone celular.

O sistema operacional do Google já tem três versões: 1.5, 1.6 e 2.0, instalados em uma base significativa de aparelhos. O desafio dos programadores é desenvolver aplicativos que rodem satisfatoriamente em múltiplos firmwares, ROMs e hardwares. Para os usuários, o resultado vem na forma de bugs em alguns aplicativos, que podem não funcionar corretamente dependendo do aparelho e, ignorando a complexidade por trás do desenvolvimento desses programas, ficam as impressões negativas.

Será que o Android vai parar na versão 2.1 pelo menos até o fim de 2010?

Fonte:
Estadão
Mobilidade é Tudo

Trabalhando com Sprites em Java ME

02 dezembro 2009 0 comentários

Este post é sobre uma palestra do Robson Soares (blog) ministrada no Javaneiros 2009, onde ele mostra o início da construção de um Jogo em Java ME. A MIDlet construída mostra um lutador fazendo movimentos básicos de socos e chutes.

Sprite utilizado:





MIDletPrincipal.java

import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;


public class MIDletPrincipal extends MIDlet {

Display display;
Jogo meujogo;

public MIDletPrincipal() {

}

protected void destroyApp(boolean arg0) throws MIDletStateChangeException {

}

protected void pauseApp() {


}

protected void startApp() throws MIDletStateChangeException {
display = Display.getDisplay(this);
meujogo = new Jogo();

display.setCurrent(meujogo);
meujogo.inicia();

}

}

Jogo.java
import java.io.IOException;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;


public class Jogo extends GameCanvas implements Runnable {

Sprite spritelutador;
Image lutador;

protected Jogo() {
super(true);

}

public void paint(Graphics arg0) {


try {
// lutador = Image.createImage("/lutador4.PNG");
// lutador4.PNG 900 x 188 pixels
lutador = Image.createImage("/lutador3.png");
// lutador4.PNG 468 x 98 pixels

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

// Lutador Maior
// spritelutador = new Sprite(lutador, 150, 188 );
spritelutador = new Sprite(lutador, 78, 98);

spritelutador.setFrame(0);
spritelutador.setPosition(20, 5);
spritelutador.paint(arg0);
}

public void inicia(){
Thread t = new Thread(this);
t.start();
}

public void run() {

Graphics g = getGraphics();
//int contador = 0;

while(true){
spritelutador.nextFrame();

//spritelutador.setFrame(contador++);
//if (contador == 6)
//  contador = 0;

spritelutador.paint(g);

flushGraphics();

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}