首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME MIDP 1.0 雙人掃雷完整實作 (二):遊戲核心邏輯與介面繪製

     編輯:J2ME

前言

接續上篇架構設計,本文詳細說明 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();
}

遞迴展開演算法 (bombOut)

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();
}

遊戲中選單 (GAMEMENU)

選項:RETURN(繼續)、RESTART(重來)、HELP(說明)、MENU(主選單)、EXIT(離開)。同主選單渲染邏輯,按鍵切換 gamestate 即可。

總結

完整實作約 500 行程式碼,涵蓋狀態機、雙緩衝繪圖、遞迴演算法、資源管理。可擴充方向:音效、藍牙對戰、AI 玩家。完整原始碼已整理打包供下載參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved