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

J2ME 俄羅斯方塊遊戲核心邏輯實現 (二):方塊運動、碰撞、消行、遊戲結束判定

     編輯:Java 相關知識

GameEngine 核心方法深度解析

承接上篇 (界面與數據結構),本文聚焦遊戲核心邏輯:方塊下落、移動、變形、碰撞檢測、消行算法、遊戲結束判定、速度控制。

方塊下落邏輯


public void brickDown() {
    if (reachBottom()) {                    // 觸底
        addBrickToMap();
        gernerateBrick();
        clearAllFullRow();
    } else {
        cRow++;                             // 正常下落一行
        if (collisWithMap()) {              // 落地碰撞 (疊加在現有方塊上)
            cRow--;                         // 回退
            addBrickToMap();                // 固化到地圖
            gernerateBrick();               // 生成新方塊
            clearAllFullRow();              // 檢查消行
        }
    }
}

雙重觸底判定:reachBottom() 檢測遊戲區域底部,collisWithMap() 檢測疊加碰撞。

觸底檢測


private boolean reachBottom() {
    int bottomRow = getBottomNotEmptyRow(); // 方塊最底部非空行 (0-3)
    return (cRow + bottomRow >= MAXROW - 1); // 方塊底部行號 >= 遊戲區最後一行
}

方塊固化到地圖


private void addBrickToMap() {
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            if (brick[brickType][index][i][j] == 1) { // 只處理實心格子
                int mapRow = cRow + i;
                int mapCol = cCol + j;
                if (mapCol >= 0 && mapCol < MAXCOL && mapRow < MAXROW) { // 邊界保護
                    map[mapRow][mapCol] = 1;
                }
            }
        }
    }
}

新方塊生成


public void gernerateBrick() {
    brickType = nextBrickType;                    // 下一個變當前
    nextBrickType = Math.abs(r.nextInt() % brick.length); // 隨機下一個
    index = 0;                                    // 重置形狀
    cRow = -3;                                    // 初始在可視區上方
    cCol = 3;                                     // 水平居中
}

方塊變形 (旋轉)


public void changeShape() {
    index++;                                      // 切換到下一種旋轉態
    if (index == brick[brickType].length) index = 0; // 循環
    
    if (testNewPosition()) {                      // 新姿態不可用?
        index--;                                  // 回退
        if (index < 0) index = brick[brickType].length - 1;
    }
}

左右移動


public void moveToLeft() {
    cCol--;
    if (testNewPosition()) cCol++; // 不可用則回退
}

public void moveToRight() {
    cCol++;
    if (testNewPosition()) cCol--;
}

新位置可用性綜合測試


private boolean testNewPosition() {
    // 1. 左邊界
    if (getLeftNotEmptyLine() + cCol < 0) return true;
    // 2. 右邊界
    if (cCol + getRightNotEmptyLine() > MAXCOL - 1) return true;
    // 3. 底部邊界
    if (getBottomNotEmptyRow() + cRow >= MAXROW - 1) return true;
    // 4. 與地圖現有方塊碰撞
    if (collisWithMap()) return true;
    return false; // 完全可用
}

邊界檢測輔助方法

方法邏輯返回值
getLeftNotEmptyLine()掃描 4x4 矩陣,最左非空列 (col 0→3)0-3
getRightNotEmptyLine()掃描 4x4 矩陣,最右非空列 (col 3→0)0-3
getBottomNotEmptyRow()掃描 4x4 矩陣,最底非空行 (row 3→0)0-3

這三個方法配合 cRow/cCol 實現精確邊界碰撞,支持異形方塊 (如 L/T/Z 型) 的不規則外緣。

地圖碰撞檢測


private boolean collisWithMap() {
    for (int col = 0; col < 4; col++) {
        for (int row = 3; row >= 0; row--) { // 從底部向上掃描,優化
            if (brick[brickType][index][row][col] == 1) {
                int mapRow = cRow + row;
                int mapCol = cCol + col;
                if (mapRow >= 0 && mapRow < MAXROW && 
                    mapCol >= 0 && mapCol < MAXCOL) {
                    if (map[mapRow][mapCol] == 1) return true; // 重疊
                }
                break; // 同列只需檢查最底部的方塊
            }
        }
    }
    return false;
}

優化:每列只檢查最底部的實心格子 (內層循環 break),減少無效比較。

消行算法

檢測滿行


private boolean isFullRow(int row) {
    int count = 0;
    for (int col = 0; col < MAXCOL; col++) 
        if (map[row][col] == 1) count++;
    return count == MAXCOL;
}

消除單行並下落


private void clearOneFullRow(int row) {
    // 上方所有行整體下移一行
    for (int i = row - 1; i >= 0; i--) {
        for (int col = 0; col < MAXCOL; col++) {
            map[i + 1][col] = map[i][col];
        }
    }
    // 頂行清零
    for (int col = 0; col < MAXCOL; col++) map[0][col] = 0;
}

消除所有滿行 (連續消行支持)


private void clearAllFullRow() {
    for (int row = MAXROW - 1; row >= 0; row--) {
        if (isFullRow(row)) {
            score += 10;              // 加分
            clearOneFullRow(row);     // 消除
            row++;                    // 關鍵:同一行下落後可能再次滿行,需重新檢查
        }
    }
}

關鍵細節:row++ 抵消外層循環的 row--,實現原地重新檢查,正確處理連續消行 (如雙消/三消/四消)。

遊戲結束判定


public boolean isGameOver() {
    cRow++; // 嘗試下落一步
    if (collisWithMap()) {            // 立即碰撞
        cRow--;                       // 還原
        if (cRow < 0) {               // 方塊還在可視區上方 (未完全進入)
            for (int row = 0; row < 4; row++) {
                for (int col = 0; col < 4; col++) {
                    if (row + cRow >= 0) break; // 已進入可視區停止檢查
                    if (brick[brickType][index][row][col] == 1) 
                        return true;  // 有方塊卡在頂部不可見區域
                }
            }
        }
    } else {
        cRow--;
    }
    return false;
}

邏輯:新方塊生成位置 cRow=-3,若頂部已堆疊導致新方塊一生成即碰撞,且方塊主體仍在可視區上方 (cRow < 0),判定遊戲結束。

速度控制


public void highSpeed() { times = 5; }   // 5倍速 (下落間隔 /5)
public void normalSpeed() { times = 1; } // 正常速

主循環中 Thread.sleep(speed / times) 實現加速效果 (按住下鍵觸發)。

渲染方法補充

當前方塊繪製


public void paintBrick(Graphics g) {
    for (int row = 0; row < 4; row++)
        for (int col = 0; col < 4; col++)
            if (brick[brickType][index][row][col] == 1) {
                int cx = (cCol + col) * CELLWIDTH;
                int cy = (cRow + row) * CELLWIDTH;
                paintCell(g, cx, cy);
            }
}

下一個方塊預覽


public void paintNextBrick(Graphics g) {
    g.drawString("下一個方塊", nextBrickX, nextBrickY, Graphics.LEFT | Graphics.TOP);
    for (int row = 0; row < 4; row++)
        for (int col = 0; col < 4; col++)
            if (brick[nextBrickType][0][row][col] == 1) { // 固定顯示第0種旋轉態
                int cx = nextBrickX + col * CELLWIDTH;
                int cy = nextBrickY + 20 + row * CELLWIDTH;
                paintCell(g, cx, cy);
            }
}

分數/等級顯示


public void paintLevelAndScore(Graphics g) {
    g.drawString("當前得分:", nextBrickX, 100, Graphics.TOP | Graphics.LEFT);
    g.drawString(String.valueOf(score), nextBrickX, 115, Graphics.LEFT | Graphics.TOP);
    g.drawString("第" + level + "關", nextBrickX, 150, Graphics.TOP | Graphics.LEFT);
}

總結

這套邏輯實現了標準俄羅斯方塊核心規則:

  1. 精確碰撞:基於 4x4 矩陣掃描的邊界/地圖碰撞,支持 7 種方塊 19 種旋轉態
  2. 平滑移動:左右/變形/下落統一由 testNewPosition() 守護
  3. 完整消行:自底向上掃描、原地重檢機制正確處理多行同消
  4. 嚴格結束判定:新方塊生成即碰撞且未完全進入可視區才判負
  5. 可擴展設計:速度控制、預覽、分數/等級顯示模塊化

代碼結構清晰、邊界條件處理完善,是 J2ME 遊戲邏輯層的優秀參考實現。

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