程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> J2ME >> 索愛MIDP 2.0手機的系統字體特效制作

索愛MIDP 2.0手機的系統字體特效制作

編輯:J2ME

 

import Java.io.IOException;
import Javax.microedition.lcdui.Graphics;
import Javax.microedition.lcdui.Image;
import Javax.microedition.lcdui.game.GameCanvas;
import Javax.microedition.lcdui.game.Sprite;
import Javax.microedition.lcdui.game.TiledLayer;

public class MyCanvas extends GameCanvas implements Runnable
{
//小船的位置
int x,y;
//小船精靈
Sprite ship;
//地圖
TiledLayer background;
//圖片
Image ship_IMG, sea_IMG, bullet_IMG;
//炮彈
Bullets bullets;
public MyCanvas()
{
super(true);
//初始化船的位置
x = 10;
y = 60;
try
{
ship_IMG = Image.createImage("/ship.png");
sea_IMG = Image.createImage("/sea.png");
bullet_IMG = Image.createImage("/bullet.png");
}
catch (IOException e)
{
e.printStackTrace();
}
//初始化炮彈
bullets = new Bullets(bullet_IMG);
//初始化小船
ship = new Sprite(ship_IMG, 24, 30);
ship.setPosition(x, y);
//初始化地圖
background = new TiledLayer(20, 6, sea_IMG, 32, 32);
background.createAnimatedTile(1);
int[][] map = new int[][]
{
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

-1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

-1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

-1, -1, -1, -1, -1 },
{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

-1, -1, -1, -1, -1 },
{ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }
};
//繪制地圖
for(int i = 0 ; i < map.length ; i ++)
{
for(int j = 0 ; j < map[i].length ; j++)
{
background.setCell(j, i, map[i][j]);
}
}
Thread th = new Thread(this);
th.start();
}

private int k = 0;
public void run()
{
Graphics g = getGraphics();
while(true)
{
//顯示出水的流動
k++;
if(k==10)
{
if(background.getAnimatedTile(-1) == 1)
{
background.setAnimatedTile(-1, 2);
}
else if(background.getAnimatedTile(-1) == 2)
{
background.setAnimatedTile(-1, 1);
}
k = 0;
}
//主控制
support(g);
//繪制
draw(g);
try
{
Thread.sleep(35);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}

public void support(Graphics g)
{
//控制船的移動及發射
int keyCode = getKeyStates();
switch(keyCode)
{
case UP_PRESSED:
y = Math.max(0, y - 2);
if(ship.getFrame() >= 2)
ship.setFrame(0);
else
ship.nextFrame();
break;
case DOWN_PRESSED:
y = Math.min(getHeight(), y + 2);
if(ship.getFrame() <= 2 || ship.getFrame() >= 5)
ship.setFrame(3);
else
ship.nextFrame();
break;
case LEFT_PRESSED:
x = Math.max(0, x - 2);
if(ship.getFrame() <= 5 || ship.getFrame() >= 8)
ship.setFrame(6);
else
ship.nextFrame();
break;
case RIGHT_PRESSED:
x = Math.min(getWidth(), x + 2);
if(ship.getFrame() <= 8 || ship.getFrame() >= 11)
ship.setFrame(9);
else
ship.nextFrame();
break;
case FIRE_PRESSED:
if(!bullets.isfire)
{
bullets.isfire = true;
bullets.setPoint(x+13,y);
}
break;
}
ship.setPosition(this.x, this.y);
}

/**
* 繪制
* @param g
*/
public void draw(Graphics g)
{
g.setColor(0xffffff);
g.fillRect(0,0,this.getWidth(),this.getHeight());
g.setColor(0x000000);
background.paint(g);
bullets.drawBullets(g);
ship.paint(g);
flushGraphics();
}
}
/**
* 炮彈
* <p>Title: Bullets</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2005</p>
* <p>Date: 2006-3-2</p>
* @author ZGY
* @version 1.0
*/
class Bullets extends Sprite
{
boolean isfire = false;
//炮彈的發射點
int bulletX, bulletY;
//炮彈的射程
int shotWidth = 50;
//炮彈的射程高度
int shotHeight = shotWidth/2-10;
//炮彈的速度
int shotSpeed = 3;
//炮彈拋物線的系數
double a,b,c;
public Bullets(Image image)
{
super(image, 15, 15);
}

/**
* 初始化炮彈
* @param x
* @param y
*/
public void setPoint(int x, int y)
{
//初始化炮彈的發射點
this.bulletX = x;
this.bulletY = y;
//根據炮彈的發射點、高度、射程計算出炮彈拋物線的三點
int x1 = bulletX;
int y1 = bulletY;
int x2 = bulletX+shotWidth/2;
int y2 = bulletY-shotHeight;
int x3 = bulletX+shotWidth;
int y3 = bulletY;
//根據拋物線方程ax^2+bx+c=y,得方程組
//ax1^2+bx1+c=y1
//ax2^2+bx2+c=y2
//ax3^2+bx3+c=y3
//解方程組得拋物線的a,b,c
b = ((y1-y3)*(x1*x1-x2*x2)-(y1-y2)*(x1*x1-x3*x3))/((x1-x3)*

(x1*x1-x2*x2)-(x1-x2)*(x1*x1-x3*x3));
a = ((y1-y2)-b*(x1-x2))/(x1*x1-x2*x2);
c = y1-a*x1*x1-b*x1;
}

/**
* 繪出炮彈
* @param g
*/
public void drawBullets(Graphics g)
{
if(isfire)
{
int k = (int)(a*bulletX*bulletX+b*bulletX+c);
setPosition(bulletX, k);
paint(g);
//炮彈的速度
bulletX += shotSpeed;
//炮彈將消失於小船的水平線
if(k > bulletY)
{
nextFrame();
if(getFrame() == 2)
{
isfire = false;
setFrame(0);
}
}
}
}
}

首先看看下圖展示的字體效果。

圖1

字體的外形是在創建Font類的時候指定的,請注意目前SonyEriCSSon的手機只實現了FACE_SYSTEM類型的字體,如果你創建的時候指定其他外觀也會自動使用FACE_SYSTEM。

Font font = Font.createFont(FONT.FACE_SYSTEM, FONT.SIZE_MEDIUM, FONT.STYLE_PLAIN);

◆FACE_SYSTEM
◆SIZE_LARGE
◆SIZE_MEDIUM
◆SIZE_SMALL
◆STYLE_BOLD
◆STYLE_ITALIC
◆STYLE_PLAIN
◆STYLE_UNDERLINED

可以在Canvas和CustomItem的界面中使用Font來裝飾界面,下面列舉幾個例子。

下面的代碼可以在Image上繪制文字,

Image fontImage = Image.createImage(width, height);
graphics = fontImage.getGraphics();
graphics.setFont(font);
graphics.setColor(0x00);
graphics.drawString("Hello World!", 0, 0, 0);

這樣在白色背景後面繪制了黑色的文字,如下:

圖2

當然,我們可以把圖片中白色的背景修改為透明的,這樣如果把Image畫到Canvas上的時候就不會顯得很突兀了(當Canvas的顏色和背景不一致的時候)。實現這個並不困難,你只需要修改Image的每個象素的Alpha值,修改為0即可。

int []data = new int[fontImage.getWidth() * fontImage.getHeight()];
fontImage.getRGB(data, 0, fontImage.getWidth(), 0, 0, fontImage.getWidth(),

fontImage.getHeight());

for(int i=0; i<data.length; i++){
if(data[i]==backgroundColor){
data[i] = (data[i]&0x00FFFFFF);
}
}

圖3

同樣的道理,我們不只可以改變透明度,還可以改變圖片象素的顏色,這樣就可以實現字顏色的漸變了。下面的代碼可以實現顏色的改變,我們要做的就是循環改變圖片的像素值,請注意每一行使用一個顏色。

int []data = new int[fontImage.getWidth() * fontImage.getHeight()];
fontImage.getRGB(data, 0, fontImage.getWidth(), 0, 0, fontImage.getWidth(),

fontImage.getHeight());
int newColor = fontColor;
int r = (fontColor & 0x00FF0000)>>16;
int g = (fontColor & 0x0000FF00)>>8;
int b = (fontColor & 0x000000FF);

int offsetR = r/fontImage.getHeight();
int offsetG = g/fontImage.getHeight();
int offsetB = b/fontImage.getHeight();
for(int i=0; i<data.length; i++){
if(data[i] != backgroundColor){
data[i] = newColor;
}
if(i%imageWidth == 0){ // subtract each color on every row.
if(r>offsetR)
r -= offsetR;
if(g>offsetG)
g -= offsetG;
if(b>offsetB)
b -= offsetB;

newColor = 0xFF000000; // make the pixel opaque.
newColor += (r<<16);
newColor += (g<<8);
newColor += b;
}
}

如果想繪制等間距的文字,那麼使用指定的寬度一個字符一個字符的畫,如下。

int charWidth = font.charWidth('W');
textWidth = charWidth * text.length();
fontImage = Image.createImage(width, weight);

graphics = fontImage.getGraphics();
graphics.setFont(font);
graphics.setColor(0x00);

for(int i=0; i<chars.length; i++){
graphics.drawChar(text.charAt(i),i*charWidth + charWidth/2, 0,

Graphics.TOP | Graphics.HCENTER);
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved