接續上篇架構設計,本文詳細說明 MiningCanvas 核心類別的遊戲畫面繪製、按鍵處理、勝負判斷與選單系統實作。
static final int MINING_MAP_GRID = 16; // 16x16 雷區
static final int BOMB_NUM = 52; // 52 顆雷
Bomb[][] bombs = new Bomb[MINING_MAP_GRID+2][MINING_MAP_GRID+2]; // 外圍加緩衝區避免越界
class Bomb {
int bombAround; // 周圍雷數
boolean isBomb; // 是否為雷
boolean hasFound; // 是否已挖開
boolean isPlayer1; // 被玩家1挖開
}
paint(Graphics g) 依 gamestate 分派:
GAMESTATE_GAMEING → paintGameScreen():private void paintGameScreen(Graphics g) {
paintPlayer(g, isPlayer1); // 外框顏色+旗幟提示當前玩家
paintMiningMap(g); // 依 bombs 狀態繪製 10x12 可視區塊
paintInfo(g); // 右側資訊欄:分數、剩餘雷數、小地圖
paintSelected(g); // 紅色圓角選擇框
}
關鍵技巧:paintX/paintY 控制可視區左上角座標,selectedX/Y 為邏輯座標(1~16),超出螢幕時自動捲動。
protected synchronized void keyPressed(int keyCode) {
int action = getGameAction(keyCode);
switch (gamestate) {
case GAMESTATE_GAMEING:
if (action == LEFT) selectedX = (--selectedX + 16) % 16;
else if (action == RIGHT) selectedX = (++selectedX) % 16;
else if (action == UP) selectedY = (--selectedY + 16) % 16;
else if (action == DOWN) selectedY = (++selectedY) % 16;
else if (action == FIRE) {
if (!bombs[selectedY+1][selectedX+1].hasFound) {
if (bombs[selectedY+1][selectedX+1].isBomb) {
// 挖到雷:加分、標記玩家、檢查勝負
} else {
// 未中雷:遞迴展開空白區 (bombOut) → 換玩家
isPlayer1 = !isPlayer1;
}
}
}
// 自動調整 paintX/Y 確保選擇框在可視範圍
break;
// ... GAMESTATE_HELP, GAMESTATE_GAMEMENU 等
}
repaint();
}
public void bombOut(int x, int y) {
if (!bombs[x][y].hasFound && inBounds(x, y)) {
bombs[x][y].hasFound = true;
if (bombs[x][y].bombAround == 0) {
bombOut(x-1, y); bombOut(x-1, y-1); bombOut(x, y-1);
bombOut(x+1, y-1); bombOut(x+1, y); bombOut(x+1, y+1);
bombOut(x, y+1); bombOut(x-1, y+1);
}
}
}
public void checkWin() {
if (player1Found > 26) { winString = "Player1 has won!"; sbWon = true; }
if (player2Found > 26) { winString = "Player2 has won!"; sbWon = true; }
if (sbWon) {
winAlert = new Alert("", winString + "\nPlayer1 " + player1Found + " : " + player2Found + " Player2", null, AlertType.INFO);
winAlert.setTimeout(Alert.FOREVER);
Display.getDisplay(miningMIDlet).setCurrent(winAlert);
gameInit(); // 重置下一局
}
}
public void gameInit() {
sbWon = false; bombInit(); player1Found = player2Found = 0;
selectedX = selectedY = 4; bombLeft = BOMB_NUM; System.gc();
}
選項:RETURN(繼續)、RESTART(重來)、HELP(說明)、MENU(主選單)、EXIT(離開)。同主選單渲染邏輯,按鍵切換 gamestate 即可。
完整實作約 500 行程式碼,涵蓋狀態機、雙緩衝繪圖、遞迴演算法、資源管理。可擴充方向:音效、藍牙對戰、AI 玩家。完整原始碼已整理打包供下載參考。