MapApi.getTilesInRect(rect) / getTilesInRect(baseTile, size)

| Chrono Divide | 3 Reads

MapApi 提供兩個同名的 getTilesInRect 多載,可依矩形座標或以「基準格+大小」的方式取得一批 Tile 物件。

在型別定義檔中可以看到這兩個簽名:

getRealMapSize(): Size;
/** Tile coordinates for each player starting position */
getStartingLocations(): Vector2[];
getTheaterType(): TheaterType;
getTile(rx: number, ry: number): Tile | undefined;
getTilesInRect(rectangle: Rectangle): Tile[];
getTilesInRect(baseTile: Tile, size: Size): Tile[];

壓縮後的實作則呼叫內部 tiles.getInRectangle,再過濾掉不在地圖邊界內的格子

getTilesInRect(e, t) {
    let tiles = t
        ? Op(this, Cp, "f").tiles.getInRectangle(e, t)
        : Op(this, Cp, "f").tiles.getInRectangle(e);
    return tiles.filter(tile => Op(this, Cp, "f").mapBounds.isWithinBounds(tile));
}

專案中的 buildingRules.ts 便透過 getTilesInRect 先取得鄰接區塊的所有格子,再依據地形或水面條件進一步篩選:

function getAdjacentTiles(game: GameApi, range: Rectangle, onWater: boolean) {
    // use the bulk API to get all tiles from the baseTile to the (baseTile + range)
    const adjacentTiles = game.mapApi
        .getTilesInRect(range)
        .filter((tile) => !onWater || tile.landType === LandType.Water);
    return adjacentTiles;
}

簡易示例

下例說明如何以這兩種呼叫方式取得地圖中心附近的格子:

import { cdapi, Bot, GameApi, Rectangle, Vector2, Size } from "@chronodivide/game-api";

class RectExampleBot extends Bot {
    onGameStart(game: GameApi) {
        const mapSize = game.mapApi.getRealMapSize();

        // 方式 1:以 Rectangle 指定區域
        const rect = { x: mapSize.width / 2 - 3, y: mapSize.height / 2 - 3, width: 6, height: 6 };
        const tilesA = game.mapApi.getTilesInRect(rect);
        console.log(`Center rect has ${tilesA.length} tiles`);

        // 方式 2:以基準格與尺寸取得
        const baseTile = game.mapApi.getTile(rect.x, rect.y);
        if (baseTile) {
            const tilesB = game.mapApi.getTilesInRect(baseTile, { width: 6, height: 6 });
            console.log(`Using base tile method => ${tilesB.length} tiles`);
        }
    }
}

async function main() {
    await cdapi.init(process.env.MIX_DIR!);
    await cdapi.createGame({
        agents: [new RectExampleBot("Checker", "Americans")],
        mapName: "mp03t4.map",
        shortGame: true,
        online: false,
    });
}
main().catch(console.error);

程式在 onGameStart 先取回地圖大小,接著:

  • Rectangle 指定中心 6×6 區塊,呼叫 getTilesInRect(rect)

  • 再以同區塊左上角的 Tile 為基準,傳入 { width: 6, height: 6 } 使用另一個多載。

兩者都會回傳位於地圖內的 Tile 陣列,可用來檢測地形或篩選可建造區域。由於方法內部透過 getInRectangle 與邊界檢查實作,查詢效率相較於逐格呼叫 getTile 更高,特別適合一次取得大量格子再做運算。

 

→返回《@chronodivide/game-api 使用教學與完整 API 對照表》

This article was last edited at