繼前兩篇完成需求分析與詳細設計後,本文呈現《華容道》遊戲核心顯示類 Displayable1 的完整實現代碼,涵蓋遊戲初始化、地圖載入、觸控/按鍵交互、繪圖渲染、移動邏輯驗證、勝利判定等全流程。代碼基於 MIDP 2.0 / CLDC 1.1 規範,適用於功能機時代的 J2ME 遊戲開發參考。
package huarongroad;
import javax.microedition.lcdui.*;
public class Displayable1 extends Canvas implements CommandListener {
// 狀態欄位
private int[] loc = new int[2]; // 光標位置 [x, y]
private int[] selectArea = new int[4]; // 選中區域 [x, y, w, h]
private int[] moveArea = new int[4]; // 目標移動區域
private Map myMap = new Map(); // 地圖模型
private boolean selected = false; // 是否已選中待移動塊
private int level = 1; // 當前關卡
// 構造器、初始化、命令處理、繪圖、邏輯方法...
}
private void jbInit() throws Exception {
selected = false;
level = 1;
Images.init(); // 載入圖片資源(單例模式)
initGame();
setCommandListener(this);
addCommand(new Command("Exit", Command.EXIT, 1));
}
private void initGame() {
loc = myMap.readMap(level); // 載入關卡地圖,返回曹操初始位置
selectArea[0] = loc[0]; selectArea[1] = loc[1];
selectArea[2] = 1; selectArea[3] = 1; // 預設選中 1x1
moveArea[0] = -1; moveArea[1] = -1; // 目標區域無效標記
moveArea[2] = 0; moveArea[3] = 0;
}
protected void paint(Graphics g) {
try {
// 1. 繪製背景框架
g.drawImage(Images.imageFrame, 0, 0, Graphics.TOP | Graphics.LEFT);
// 2. 繪製地圖所有塊
myMap.drawMap(g);
// 3. 繪製選中框(綠色)
if (selected) g.setColor(0, 255, 0);
g.drawRect(selectArea[0]*UNIT+LEFT, selectArea[1]*UNIT+TOP,
selectArea[2]*UNIT, selectArea[3]*UNIT);
g.setColor(255, 255, 255);
// 4. 繪製目標移動框(洋紅)
if (selected) {
g.setColor(255, 0, 255);
g.drawRect(moveArea[0]*UNIT+LEFT, moveArea[1]*UNIT+TOP,
moveArea[2]*UNIT, moveArea[3]*UNIT);
g.setColor(255, 255, 255);
}
} catch (Exception ex) { /* 靜默吞沒,避免繪圖崩潰 */ }
// 記憶體監控(調試用)
System.out.println(Runtime.getRuntime().freeMemory());
}
setRange():根據光標位置計算實際選中塊的邊界(處理 1x2、2x1、2x2 不同尺寸塊)
setMoveRange():驗證目標位置是否可移動(邊界檢查、碰撞檢查、空白格檢查)
private boolean setMoveRange() {
// 遍歷選中區域所有格子
for (int i = 0; i < selectArea[2]; i++) {
for (int j = 0; j < selectArea[3]; j++) {
int tx = loc[0] + i, ty = loc[1] + j;
// 越界或目標非空白且非選中區域內部 → 不可移動
if (ty >= HEIGHT || tx >= WIDTH ||
(!isInRange(tx, ty) && myMap.grid[ty][tx] != BLANK)) {
return false;
}
}
}
// 記錄合法目標區域
moveArea[0] = loc[0]; moveArea[1] = loc[1];
moveArea[2] = selectArea[2]; moveArea[3] = selectArea[3];
return true;
}
protected void keyPressed(int keyCode) {
switch (getGameAction(keyCode)) {
case Canvas.UP: moveCursor(0, -1); break;
case Canvas.DOWN: moveCursor(0, +1); break;
case Canvas.LEFT: moveCursor(-1, 0); break;
case Canvas.RIGHT: moveCursor(+1, 0); break;
case Canvas.FIRE: handleFire(); break;
}
}
private void moveCursor(int dx, int dy) {
int nx = loc[0] + dx, ny = loc[1] + dy;
if (nx < 0 || nx >= WIDTH || ny < 0 || ny >= HEIGHT) return;
loc[0] = nx; loc[1] = ny;
if (!selected) {
setRange(); // 未選中時:移動光標並重新計算選中區域
} else {
if (setMoveRange()) { /* 合法目標 */ }
else { loc[0] -= dx; loc[1] -= dy; } // 非法則回退
}
repaint();
}
private void handleFire() {
if (selected) {
moveBlock(); // 執行移動
selected = false;
if (checkWin()) System.out.println("WIN!");
} else {
// 未選中時:若光標處非空白則進入選中狀態
if (myMap.grid[loc[1]][loc[0]] != BLANK) selected = true;
}
repaint();
}
private void moveBlock() {
// 1. 備份選中區域數據
byte[][] temp = new byte[selectArea[3]][selectArea[2]];
for (int i = 0; i < selectArea[2]; i++)
for (int j = 0; j < selectArea[3]; j++)
temp[j][i] = myMap.grid[selectArea[1]+j][selectArea[0]+i];
// 2. 將選中區域複製到目標區域
for (int i = 0; i < selectArea[2]; i++)
for (int j = 0; j < selectArea[3]; j++)
myMap.grid[moveArea[1]+j][moveArea[0]+i] = temp[j][i];
// 3. 清空選中區域中不在目標區域的殘留格子
for (int i = 0; i < selectArea[3]; i++)
for (int j = 0; j < selectArea[2]; j++)
if (!isInRange2(selectArea[0]+j, selectArea[1]+i))
myMap.grid[selectArea[1]+i][selectArea[0]+j] = BLANK;
// 4. 重置狀態
selectArea[0] = moveArea[0]; selectArea[1] = moveArea[1];
moveArea[0] = -1; moveArea[1] = -1; moveArea[2] = 0; moveArea[3] = 0;
}
private boolean checkWin() {
// 曹操 (CAOCAO) 到達右下出口位置
return myMap.grid[HEIGHT-2][WIDTH-3] == CAOCAO;
}
Images.init() 集中載入所有 PNG,遊戲結束時釋放paint() 中輸出剩餘/總記憶體,針對 500KB-2MB 堆優化printGrid() 打印地圖矩陣,移動前後對比驗證邏輯selected 布爾標誌驅動「選中→移動→釋放」三態流轉src/huarongroad/res/本文呈現了 J2ME 遊戲核心邏輯的完整實現:從資源載入、狀態管理、輸入處理、碰撞檢測、繪圖渲染到勝利判定。雖然平台已成歷史,但有限資源下的狀態機設計、繪圖管線優化、記憶體精細控制、邏輯與渲染分離等工程思想,在現代嵌入式、物聯網、WebAssembly 遊戲開發中依然極具參考價值。