在功能機時代,掃雷是展示 J2ME 遊戲邏輯與界面分離的絕佳案例。本文將帶你從零開始,解析一個完整的掃雷遊戲如何在 J2ME 平台上落地,涵蓋數據結構設計、地雷生成算法、遞歸展開邏輯,以及 MIDlet、Canvas 與遊戲邏輯類的三層架構實現。
遵循 Java 開發慣例,J2ME 遊戲通常劃分為三個核心模組:
MIDlet,負責生命週期管理與應用啟動。Canvas 並實現 CommandListener,處理繪製、鍵盤事件及菜單命令(如「新遊戲」、「退出」)。gamelogic,封裝棋盤數據、地雷分佈、勝負判定等核心算法,與界面零耦合。這種「邏輯與界面分離」的思想,是 Java 開發中極具價值的工程實踐。
掃雷地圖本質是矩形網格,使用 int[][] pan 即可表示。為了在同一數組中區分「未翻開」、「已翻開」及「地雷」,採用巧妙的數值編碼:
20:標識地雷位置。<=10:未翻開的方塊,數值即周圍地雷數(0-8)。>=10:已翻開的方塊,數值減 10 即周圍地雷數。翻開操作只需 pan[i][j] += 10,極其高效。
public void InitArray() {
// 1. 清零棋盤
for (int i=0; i<8; i++)
for (int j=0; j<8; j++) pan[i][j] = 0;
// 2. 隨機佈雷(約 15 個,允許重複)
RandomArray();
// 3. 計算每格周圍地雷數
CountBomb();
// 4. 統計總地雷數
BombNum = Bomb();
}
RandomArray 利用 Math.abs(random.nextInt()) % 64 映射到 8x8 棋盤;CountBomb 遍歷八個方向檢測地雷,邊界條件嚴謹處理。
當玩家點擊數值為 0 的格子(case 0),觸發 isNull(matrix) 遞歸:
(i-1 >= 0) && (j-1 >= 0) 確保不越界。這實現了經典掃雷「一點開一片」的爽快體驗。
public boolean isWin() {
// 總格數 64 = 地雷數 + 已翻開非地雷數
if ((BombNum + countOpen()) == 64) {
GameOver = true;
return true;
}
return false;
}
gameCanvas 繼承 Canvas 並實現 CommandListener,核心職責:
initializeBoard() 根據螢幕長寬動態計算格子大小、棋盤左上角坐標,確保橫豎屏皆可完美顯示。paint() 中調用 game.isWin() 判斷遊戲結束,分別調用 paintGame() 或 paintGameOver()。game.openpan(),長按或菜單觸發標記地雷/取消標記。Vector BombVector 記錄玩家標記位置,輔助防誤觸。| 文件 | 核心類/接口 | 關鍵方法 |
|---|---|---|
| gamelogic.java | class gamelogic | InitArray, RandomArray, CountBomb, openpan, isNull, isWin, getBomb |
| gameCanvas.java | class gameCanvas extends Canvas implements CommandListener | initializeBoard, paint, commandAction, keyPressed, addBomb/delBomb/searchBomb |
| Control.java (MIDlet) | class control extends MIDlet | startApp, pauseApp, destroyApp |
這個掃雷實現雖代碼樸素,卻完整展示了 J2ME 遊戲開發的精髓:
isNull 遞歸展開是處理連通區域的教科書級寫法。boardCellSize 適配千奇百怪的功能機螢幕。若你正在學習 J2ME 或嵌入式遊戲開發,建議完整敲一遍此代碼,並嘗試擴展:增加難度選擇、計時器、最高分記錄(RMS 持久化),將其打磨成一款可發布的迷你佳作。