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

J2ME 動態場景系統:TiledLayer 擴展實現無限捲動地形、障礙生成與碰撞檢測

     編輯:J2ME

前言:場景是遊戲的靈魂

在《Death Flight》中,場景不是預製地圖,而是程序化生成、無限捲動、即時碰撞檢測的動態系統。作者擴展 TiledLayer 打造 Terrain 類別,單一類別承擔:地形生成、障礙放置、捲動渲染、碰撞判定、分數計算。本文深度拆解其核心演算法與工程細節。

TiledLayer 速查:為什麼它是捲動場景的最佳選擇

關鍵洞見: 不要逐格 drawImage,改用 setCell 修改邏輯矩陣 + setPosition 整層位移,效能提升 10 倍以上。

Terrain 類別架構

public class Terrain extends TiledLayer {
    // 參數
    public int milemeter = 0;      // 飛行距離(分數)
    public int speed = 0;          // 捲動速度(幀間隔),主選單可調
    private int timestamp = 0;     // 幀計數器
    private int tileW, tileH;      // 圖塊尺寸
    private int[][] gameMap;       // 邏輯地圖 [Rows][Cols]
    private int[] indexMap;        // 行映射:實現 O(1) 捲動
    private Random random;
    private Helicopter player;     // 碰撞檢測參考

    // 地形狀態
    private int upBound, lowBound; // 上下邊框邊界(列索引)
    private int wallHeight;        // 障礙高度(格數)
    private int wallPos;           // 障礙水平位置
    private boolean up_down;       // 地形上升/下降
    private int alterSpeed, alterExtent; // 變化速度/持續格數
    private int layerTop;          // 視覺平滑捲動偏移
}

構造函數:初始化邏輯矩陣與行映射

public Terrain(int cols, int rows, Image img, int tileW, int tileH, Helicopter player) {
    super(cols, rows, img, tileW, tileH); // 父類建構:建立圖塊集
    this.player = player; this.tileW = tileW; this.tileH = tileH;
    this.screenW = getWidth(); this.screenH = getHeight();
    this.Rows = rows; this.Cols = cols;
    random = new Random(); layerTop = -tileH;

    // 1. 行映射陣列:indexMap[i] = 邏輯行號 → 物理行 i 顯示哪一行邏輯資料
    indexMap = new int[Rows];
    for (int i=0; i= Cols - Cols/7) gameMap[r][c] = 1; // 磚塊索引 1

    // 3. 同步到 TiledLayer
    for (int r=0; r

行映射技巧:O(1) 捲動的核心

傳統做法:每幀將 gameMap 所有行向上搬移一格 → O(Rows×Cols)。
indexMap 做法:只搬移索引陣列 → O(Rows)。

// 每幀更新時
for (int i=0; i

核心更新邏輯 update():地形演化與障礙生成

public void update() {
    if (++timestamp > speed) { // 速度控制:每 speed 幀更新一次
        timestamp = 0;
        if (layerTop == 0) { // 整格捲動完成,處理邏輯
            milemeter++; // 分數+1

            // 1. 清空最新行(即將進入畫面的行)中間區域
            for (int c=upBound+1; c 0) { // 正在變化中
                if (up_down) { upBound -= alterSpeed; lowBound -= alterSpeed; } // 上升
                else { upBound += alterSpeed; lowBound += alterSpeed; } // 下降
                // 邊界夾擠保護
                if (upBound < 0) { upBound += alterSpeed; lowBound += alterSpeed; }
                if (lowBound >= Cols-1) { upBound -= alterSpeed; lowBound -= alterSpeed; }
                // 依新邊界填充牆壁
                for (int c=0; c= lowBound) gameMap[indexMap[Rows-1]][c] = 1;
                alterExtent--;
            } else { // 產生新變化
                alterExtent = Math.abs(random.nextInt() % 10);
                if (alterExtent == 0) alterExtent = 5; // 避免 0
                up_down = (random.nextInt() % 2 == 0); // 隨機上升/下降
                alterSpeed = Math.abs(random.nextInt()) % 3 + 1; // 1~3 格/步
                // 注意:此處 return,新變化下一幀才開始生效
                return;
            }

            // 3. 定期生成障礙(每 10 米一個)
            if (milemeter % 10 == 0) {
                wallPos = Math.abs(random.nextInt()) % (Cols - wallHeight);
                for (int c=0; c

演算法關鍵點解析

  1. 雙層速度控制: speed 控制邏輯更新頻率(難度),layerTop++ 控制視覺平滑度(每幀 1 像素)。
  2. 地形變化狀態機: alterExtent 剩餘步數,up_down 方向,alterSpeed 步長。邊界夾擠防止超出螢幕。
  3. 障礙生成規則: 固定間距(10 米)、隨機水平位置、固定高度,確保可通過縫隙存在。
  4. 只更新可見區: setCell 僅針對物理第 0 行,其餘行靠 setPosition 整層位移,極致效能。

碰撞檢測:矩形與網格的高效交集

public boolean collides() {
    Rect pr = player.getPlayerRect(); // 像素座標
    // 轉換為網格座標範圍
    int r1 = pr.top / tileH, r2 = pr.bottom / tileH;
    int c1 = pr.left / tileW, c2 = pr.right / tileW;
    for (int r=r1; r<=r2; r++)
        for (int c=c1; c<=c2; c++)
            if (gameMap[indexMap[r]][c] == 1) return true; // 撞到磚塊
    return false;
}
  • 僅檢測直升機包圍盒覆蓋的格子(最多 3×4 格),O(1)。
  • 利用 indexMap 直接查詢邏輯地圖,無需反推視覺座標。

效能與記憶體分析

方法用途
setCell(col, row, tileIndex)設定單元格圖塊索引(0=透明)
setPosition(x, y)整層平移,配合 paint(g) 實現硬體加速捲動
paint(Graphics g)一次繪製整層可見區域,內部優化裁剪

擴展建議:從硬編碼到數據驅動

// 難度曲線數據化
class LevelConfig {
    int baseSpeed;        // 捲動速度
    int terrainVolatility; // alterExtent 範圍
    int obstacleFrequency; // 米數間隔
    int obstacleHeight;    // 格數
    int gapMinWidth;       // 最小通道寬度
}
// Terrain 持有 LevelConfig,關卡切換只需替換配置物件

總結

Terrain 展示了在 J2ME 環境下,如何以 TiledLayer + 環狀索引映射 + 狀態機地形演化 實現商業級無限捲動場景。其核心智慧在於:

  1. 邏輯與視覺解耦: gameMap 存邏輯,indexMap 控捲動,layerTop 控平滑。
  2. 最小化繪圖指令: 單行 setCell + 整層 setPosition,零 drawImage 迴圈。
  3. 程序化內容可控: 參數化地形波動、障礙頻率、通道寬度,支援難度曲線設計。

此架構可直接移植至現代引擎:Tilemap (Unity/Godot) + Circular Buffer 行索引 + Coroutine 地形生成器,思維完全通用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指標數值說明
邏輯地圖大小Rows × Cols × 4 bytes例:10×20 = 800 bytes
索引映射Rows × 4 bytes40 bytes
每幀 setCell 次數Cols僅更新 1 行,極省 CPU
碰撞檢測複雜度O(覆蓋格數)常數級