The tilemap panel gains Fill and Pick: Fill floods the connected cells of the active layer that carry the same tile (edge neighbours only, bounded by the grid) as one undo step, Pick takes the tile of the clicked cell on the active layer, and holding Alt picks while any tool is active (#133)
game-maker / gate (push) Successful in 1m41s
game-maker / suite (push) Successful in 6m7s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-18 12:31:19 +02:00
1 parent c2fd536aaf
commit 0b32d3cbf3
9 files changed
+350 -20

No files matched your search

+37
View File
@@ -178,6 +178,43 @@ export function cellsInRect(
return cells;
}
/**
* The cells a fill from `start` changes (#133): every cell reached through its four edge
* neighbours that holds what `start` holds – empty included – clipped to the grid. Diagonals do not
* count, or a fill would leak through the gap between two corners. Filling with the tile already
* there changes nothing, so that returns no cells.
*/
export function floodFill(
props: PropertyBag,
layer: TilemapLayer,
start: { x: number; y: number },
tileId: string,
): { x: number; y: number }[] {
if (!inGrid(props, start.x, start.y)) return [];
const from = cellAt(layer, start.x, start.y);
if (from === tileId) return [];
// The list is its own queue: everything in it is filled, and it is walked while it grows.
const cells = [{ x: start.x, y: start.y }];
const seen = new Set([cellKey(start.x, start.y)]);
for (let index = 0; index < cells.length; index++) {
const cell = cells[index]!;
for (const [dx, dy] of [
[0, -1],
[1, 0],
[0, 1],
[-1, 0],
] as const) {
const x = cell.x + dx;
const y = cell.y + dy;
const key = cellKey(x, y);
if (seen.has(key) || !inGrid(props, x, y) || cellAt(layer, x, y) !== from) continue;
seen.add(key);
cells.push({ x, y });
}
}
return cells;
}
/**
* The cells a stroke from one cell to another covers. A pointer jumps between events, so without
* this a fast drag would paint dots instead of a line.