Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 1x 1x 1x 1x 1x 9x 9x 9x 11x 9x 3x 6x 1x 5x 2x 3x | import { TILE_SIZE } from "consts";
import { CollisionTileDef } from "shared/lib/resources/types";
const collisonTileMaskCache: Record<string, ImageData> = {};
const collisonTileCache: Record<string, HTMLCanvasElement> = {};
export const renderCollisionTileIcon = (
icon: string,
color: string,
): HTMLCanvasElement => {
const key = `${color}:${icon}`;
// Use cached if available
const cachedIcon = collisonTileCache[key];
Iif (cachedIcon) {
return cachedIcon;
}
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
Iif (!ctx) {
throw new Error("Unable to create canvas context");
}
// Convert icon to binary representation
const iconBits = icon
.split("")
.map((c) => parseInt(c, 16).toString(2).padStart(4, "0"))
.join("");
// Use cached mask if available
let maskData = collisonTileMaskCache[icon];
Iif (!maskData) {
maskData = ctx.getImageData(0, 0, TILE_SIZE, TILE_SIZE);
// Draw mask
for (let y = 0; y < TILE_SIZE; y++) {
for (let x = 0; x < TILE_SIZE; x++) {
const i = x + y * TILE_SIZE;
const ii = i * 4;
maskData.data[ii + 3] = iconBits[i] === "1" ? 255 : 0;
}
}
}
ctx.putImageData(maskData, 0, 0);
// Fill color over mask
ctx.fillStyle = color;
ctx.globalCompositeOperation = "source-in";
ctx.fillRect(0, 0, TILE_SIZE, TILE_SIZE);
// Cache result
collisonTileMaskCache[icon] = maskData;
collisonTileCache[key] = canvas;
return canvas;
};
export const isCollisionTileActive = (
value: number,
tileDef: CollisionTileDef,
tileDefs: CollisionTileDef[],
): boolean => {
const mask = tileDef.mask || 0xff;
const maskedValue = value & mask;
const exactMatch = tileDefs.find(
(td) => td.flag === (value & (td.mask ?? 0xff)),
);
if (tileDef === exactMatch) {
// Exact match found and this is that tile
return true;
} else if (exactMatch) {
// Exact match found but it wasn't this tile
return false;
} else if (tileDef.multi) {
return (
// Full mask not selected
maskedValue !== mask &&
// But flag bits are
(maskedValue & tileDef.flag) !== 0
);
} else {
return maskedValue === tileDef.flag;
}
};
|