← Level pieces 23D assetfogon/nivel-bloque-tnt
Caja de TNT
Drag to turn it// «Caja de TNT» · gpt-6-sol (medium)
// A wooden TNT crate: a cube 36x36x36 centered, red painted wood planks in 3 shades with darker plank seams, light wooden corner trims, and big white TNT letters on all four sides.
// 36 × 36 × 36 crate, centered on the grid.
const lo = 6, hi = 41;
const red = ["#df3e35", "#d73730", "#e5483a"];
const seam = "#a72d29";
const wood = "#e9b96c";
const woodLight = "#f5d38b";
const woodDark = "#bd8348";
box(lo, lo, 0, hi, hi, 35, red[0]);
// Broad painted planks and crisp seams on the four walls.
for (let z = 2; z <= 33; z++) {
const shade = red[Math.floor((z - 2) / 6) % 3];
for (let u = 6; u <= 41; u++) {
set(u, lo, z, shade);
set(u, hi, z, shade);
set(lo, u, z, shade);
set(hi, u, z, shade);
}
}
for (let z = 7; z <= 32; z += 6) {
for (let u = 6; u <= 41; u++) {
set(u, lo, z, seam);
set(u, hi, z, seam);
set(lo, u, z, seam);
set(hi, u, z, seam);
}
}
// Red boards on the lid, running front to back.
for (let x = lo; x <= hi; x++) {
const shade = red[Math.floor((x - lo) / 12) % 3];
for (let y = lo; y <= hi; y++) set(x, y, 35, shade);
}
for (const x of [17, 29]) {
box(x, lo, 35, x, hi, 35, seam);
}
// Pale wooden corner posts and sturdy upper and lower rims.
for (const x of [lo, hi - 2]) {
for (const y of [lo, hi - 2]) {
box(x, y, 0, x + 2, y + 2, 35, wood);
box(x, y, 3, x + 2, y + 2, 3, woodDark);
box(x, y, 33, x + 2, y + 2, 33, woodLight);
}
}
for (const z of [0, 1, 34, 35]) {
for (let u = lo; u <= hi; u++) {
const c = z === 1 ? woodDark : z === 35 ? woodLight : wood;
set(u, lo, z, c);
set(u, hi, z, c);
set(lo, u, z, c);
set(hi, u, z, c);
}
}
// The top rim continues around the lid.
for (let x = lo; x <= hi; x++) {
for (let y = lo; y <= hi; y++) {
if (x <= 7 || x >= 40 || y <= 7 || y >= 40) {
set(x, y, 35, woodLight);
}
}
}
// Coordinates on any of the four outward-facing walls.
function face(side, u, z, color) {
if (side === 0) set(lo + u, lo, z, color);
if (side === 1) set(hi - u, hi, z, color);
if (side === 2) set(lo, hi - u, z, color);
if (side === 3) set(hi, lo + u, z, color);
}
const pixels = [];
function letterPixel(u, z) { pixels.push([u, z]); }
// Two chunky T's.
for (const start of [4, 24]) {
for (let u = start; u < start + 8; u++) {
for (let z = 25; z <= 27; z++) letterPixel(u, z);
}
for (let u = start + 3; u <= start + 4; u++) {
for (let z = 10; z <= 24; z++) letterPixel(u, z);
}
}
// Thick upright strokes and a descending diagonal make the N.
for (let z = 10; z <= 27; z++) {
for (const u of [14, 15, 20, 21]) letterPixel(u, z);
const diagonal = 15 + Math.round((27 - z) * 5 / 17);
letterPixel(diagonal, z);
letterPixel(diagonal + 1, z);
}
// A one-block dark drop shadow gives the white paint contrast over seams.
for (let side = 0; side < 4; side++) {
for (const [u, z] of pixels) face(side, u + 1, z - 1, "#9a302a");
for (const [u, z] of pixels) {
face(side, u, z, z >= 25 ? "#ffffff" : "#f5f1e6");
}
// Small, tidy nail heads in the wooden frame.
for (const u of [5, 30]) {
for (const z of [4, 31]) {
face(side, u, z, "#ad7846");
face(side, u, z + 1, "#fff0ba");
}
}
}import { draw } from "./assets/voxel";
import { nivelBloqueTnt } from "./assets/nivel-bloque-tnt";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, nivelBloqueTnt, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add nivel-bloque-tnt
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["nivel-bloque-tnt"] })
# It lands in client/assets/nivel-bloque-tnt.ts
# https://fogon.page/object/nivel-bloque-tnt