利用 Canvas 繪圖與簡單的正弦位移陣列,即可實現會「跳動」的波浪文字效果。本文提供完整 MIDlet 範例,核心邏輯只需 30 行程式碼,適合初學者理解動畫迴圈與像素級繪圖控制。
文字「PRESS 5」逐字上下波動,並以雙重繪製模擬粗體,背景白、前景黑,波峰以品紅色顯示「drawing...」提示。
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class WaveTextDemo extends MIDlet implements CommandListener {
private Command exitCmd;
private WaveCanvas canvas;
public WaveTextDemo() {
exitCmd = new Command("Exit", Command.EXIT, 1);
canvas = new WaveCanvas();
canvas.addCommand(exitCmd);
canvas.setCommandListener(this);
Display.getDisplay(this).setCurrent(canvas);
}
protected void startApp() {}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable d) {
if (c == exitCmd) { destroyApp(false); notifyDestroyed(); }
}
}
class WaveCanvas extends Canvas implements Runnable {
private static final String TEXT = "PRESS 5";
// 預計算的垂直位移表(模擬正弦波)
private final int[] dy = {0,0,0,0,0,0,0,1,2,3,3,2,1,0,0,0,0,0,0,0};
private boolean running = true;
private int frame = 6; // 起始相位
private final int CHAR_W = 7; // 估計字元寬度
public WaveCanvas() {
new Thread(this).start();
}
protected void paint(Graphics g) {
int w = getWidth(), h = getHeight();
g.setColor(0xFFFFFF); g.fillRect(0, 0, w, h);
g.setColor(0x000000);
for (int i = 0; i < TEXT.length(); i++) {
int x = 20 + i * CHAR_W;
int y = 10 - dy[(frame - i + dy.length) % dy.length];
String ch = TEXT.substring(i, i+1);
g.drawString(ch, x, y, Graphics.TOP | Graphics.LEFT);
g.drawString(ch, x+1, y+1, Graphics.TOP | Graphics.LEFT); // 加粗
}
}
public void run() {
while (running) {
repaint();
try { Thread.sleep(70); } catch (InterruptedException ignore) {}
frame++; if (frame >= dy.length) frame = 6;
}
}
}
Math.sin 運算,嵌入式裝置無 FPU 時效能差異巨大。(frame - i + len) % len 讓每個字元錯開相位,形成波浪傳遞感。repaint() → 系統回呼 paint(),配合 Thread.sleep 控制幀率(約 14 FPS)。dy[i] = (int)(amplitude * Math.sin(2*Math.PI*i/period))。TEXT 改為建構子參數。這個小範例展示了 J2ME 在極簡 API 下仍能創造生動視覺效果的能力,歡迎直接複製修改應用於專案中。