关于 spritecook-use-dual-grid-tilesets
为在游戏引擎或自定义渲染器中使用 SpriteCook 双网格 15 片地形图集提供实现指南,适合负责地形渲染的开发者。内容明确规定逻辑单元采样、掩码到图集帧的映射,以及双地形渲染方式。
主要功能
- 01四个逻辑单元生成 4 位掩码
- 02掩码映射到 4×4 图集帧
- 03支持双地形底层渲染
- 04提供边界与像素缩放提示
适用场景
- 01在游戏引擎中实现地形图集渲染
- 02为双地形地图绘制基础地表
- 03排查大块填充区域的接缝
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ spritecook/ skills --skill spritecook-use-dual-grid-tilesets安装后在 Claude Code 中输入/spritecook-use-dual-grid-tilesets确认已加载。
详细介绍
SpriteCook 双网格 15 块图块集
在游戏引擎或自定义渲染器中实现自上而下视角的 SpriteCook 15 块图块集时,请使用此技能。
此技能用于使用生成的图块集。生成图块集时,请使用 spritecook-generate-tilesets。
概念
双网格图块集将地形存储为逻辑绘制单元,然后在这些单元之间渲染可见图块。每个渲染图块根据其周围的四个逻辑单元来选择。
对于每个渲染图块,采样:
- 左上逻辑单元
- 右上逻辑单元
- 左下逻辑单元
- 右下逻辑单元
这四个单元的模式会变成一个 4 位掩码。该掩码从 4x4 的 15 块图集里选择一个帧。
掩码顺序
使用 SpriteCook 当前的掩码位顺序:
let mask = 0
if (filled(x - 1, y - 1)) mask |= 1 // top-left
if (filled(x, y - 1)) mask |= 2 // top-right
if (filled(x - 1, y )) mask |= 4 // bottom-left
if (filled(x, y )) mask |= 8 // bottom-right
掩码 0 不会渲染任何内容。其他掩码通过以下查找表映射到 4x4 图集:
const frameByMask = [
-1,
15,
8,
9,
0,
11,
14,
7,
13,
4,
1,
10,
3,
2,
5,
6,
]
图集单元为:
const frame = frameByMask[mask]
if (frame < 0) return null
const atlasColumn = frame % 4
const atlasRow = Math.floor(frame / 4)
渲染器伪代码
type CellMap = boolean[] // width * height logical terrain cells
function cellIndex(x: number, y: number, columns: number) {
return y * columns + x
}
function isFilled(cells: CellMap, x: number, y: number, columns: number, rows: number) {
return x >= 0 && y >= 0 && x < columns && y < rows && cells[cellIndex(x, y, columns)] === true
}
function dualGridMask(cells: CellMap, x: number, y: number, columns: number, rows: number) {
let mask = 0
if (isFilled(cells, x - 1, y - 1, columns, rows)) mask |= 1
if (isFilled(cells, x, y - 1, columns, rows)) mask |= 2
if (isFilled(cells, x - 1, y, columns, rows)) mask |= 4
if (isFilled(cells, x, y, columns, rows)) mask |= 8
return mask
}
function atlasCellForMask(mask: number) {
const frameByMask = [-1, 15, 8, 9, 0, 11, 14, 7, 13, 4, 1, 10, 3, 2, 5, 6]
const frame = frameByMask[Math.max(0, Math.min(15, Math.floor(mask)))]
if (frame < 0) return null
return { column: frame % 4, row: Math.floor(frame / 4) }
}
function renderDualGrid(ctx, atlasImage, cells: CellMap, columns: number, rows: number, tileSize: number) {
for (let y = 0; y <= rows; y += 1) {
for (let x = 0; x <= columns; x += 1) {
const mask = dualGridMask(cells, x, y, columns, rows)
const atlasCell = atlasCellForMask(mask)
if (!atlasCell) continue
ctx.drawImage(
atlasImage,
atlasCell.column * tileSize,
atlasCell.row * tileSize,
tileSize,
tileSize,
x * tileSize,
y * tileSize,
tileSize,
tileSize,
)
}
}
}
双地表图块集
使用 edges="two_surfaces" 生成的图块集(例如草地和水)具有第二种地形。帧查找不会使用图集帧 12(第 0 列、第 3 行,即左下角的单元)。在双地表图块集中,该单元存放完整的反向地表图块,例如开阔水域。
先绘制反向地表,再在其上绘制掩码图块:
const counterSurfaceCell = { column: 0, row: 3 }
function renderTwoSurfaceDualGrid(ctx, atlasImage, cells: CellMap, columns: number, rows: number, tileSize: number) {
for (let y = 0; y <= rows; y += 1) {
for (let x = 0; x <= columns; x += 1) {
ctx.drawImage(
atlasImage,
counterSurfaceCell.column * tileSize,
counterSurfaceCell.row * tileSize,
tileSize,
tileSize,
x * tileSize,
y * tileSize,
tileSize,
tileSize,
)
}
}
renderDualGrid(ctx, atlasImage, cells, columns, rows, tileSize)
}
如果没有这个底层,掩码 0 区域会呈现透明,第二种地形也会消失。对于单地表(transparent 边缘)图块集,该单元为空;请跳过底层绘制。
实用说明
- 渲染时,图块的列数和行数都要比逻辑地图多一个,因为渲染图块位于已绘制逻辑单元周围。
- 对于像素艺术,请禁用平滑处理并使用最近邻缩放。
- 将掩码
15视为填充内部图块,将掩码0视为透明/不绘制。在双地表图块集中,掩码0会显示反向地表底层。 - 发布图块集前,请绘制测试地图。如果完整图块(掩码
15)无法无缝衔接,大面积填充区域就会出现明显的棋盘格。 - 请严格将生成的图集视为由大小相同的图块单元组成的 4x4 网格。
- 请勿将该图集重新解读为普通的 8 邻接块状图块集;此映射专用于 SpriteCook 的双网格 15 块布局。
评论
支持 Markdown