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

2D 遊戲地圖系統設計與高效繪製技巧

     編輯:J2ME

地圖資料來源

地圖並非手寫陣列,而是由地圖編輯器(如 Mappy、自製工具)產出,再匯出為二進位或文字格式嵌入程式。常見視角:俯視(RPG、SLG)、側視(動作)、45 度斜視。本文以俯視角為例。

地圖資料結構範例

// 24×10 地圖,0=地板,1=牆壁
public static final byte[][] MAP_DATA = {
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
    {0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    {0,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0},
    {0,1,0,0,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0},
    {0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0}
};

座標系統與可視區域

  • 地圖塊大小:TILE_W, TILE_H。
  • 地圖絕對座標:mapX, mapY(左上角在螢幕位置,負值表示向左/上捲動)。
  • 螢幕尺寸:SCR_W, SCR_H。
  • 可視塊數:MAX_COL = SCR_W/TILE_W + 2, MAX_ROW = SCR_H/TILE_H + 2(+2 保證邊緣完整)。

繪製方案比較

方案一:遍歷整張地圖 + 邊界裁剪(低效)

int drawnRows = 0;
for (int r = startRow; r < MAP_DATA.length; r++) {
    boolean any = false;
    for (int c = startCol; c < MAP_DATA[r].length; c++) {
        int x = mapX + c * TILE_W;
        int y = mapY + r * TILE_H;
        if (x <= SCR_W && y <= SCR_H && x >= -TILE_W && y >= -TILE_H) {
            g.drawImage(tiles[MAP_DATA[r][c]], x, y, Graphics.TOP|Graphics.LEFT);
            any = true;
            if (++drawnCols > MAX_COL) break;
        }
    }
    if (any) if (++drawnRows > MAX_ROW) break;
}

缺點:地圖越大、迴圈越長,FPS 隨地圖尺寸線性下降。

方案二:直接計算可視範圍索引(推薦,O(1) 定位)

// 計算左上角對應的地圖陣列索引
int startCol = (-TILE_W - mapX) / TILE_W;
int startRow = (-TILE_H - mapY) / TILE_H;
if (startCol < 0) startCol = 0;
if (startRow < 0) startRow = 0;

for (int r = startRow; r < startRow + MAX_ROW; r++) {
    for (int c = startCol; c < startCol + MAX_COL; c++) {
        if (r < 0 || c < 0 || r >= MAP_DATA.length || c >= MAP_DATA[0].length) continue;
        int x = mapX + c * TILE_W;
        int y = mapY + r * TILE_H;
        g.drawImage(tiles[MAP_DATA[r][c]], x, y, Graphics.TOP|Graphics.LEFT);
    }
}

優點:迴圈次數固定 = 可視塊數,與地圖總大小無關,FPS 恆定。

進階應用

  • 多層地圖:背景層、阻擋層、事件層分離,繪製順序固定。
  • 動態地圖塊:tiles[] 可存放 AnimatedTile 物件,paint() 內部自動播放幀。
  • 大地圖分頁載入:將超大地圖切割為多個區塊檔,跨區時動態載入/卸載。
  • 碰撞檢測:直接查 MAP_DATA[r][c] 判斷可通行性,無需額外結構。

程式碼復用性

核心繪製邏輯僅依賴 mapX/mapY,遊戲主迴圈只需更新這兩值(跟隨主角、鏡頭震動、過場移動),即可復用於 RPG、SLG、解謎等多類型專案。

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