← Parties and Christmas3D assetfogon/pila-de-regalos
Pila de regalos
Drag to turn it// «Pila de regalos» · gpt-6-sol (medium)
// A cheerful pile of five gift boxes of different sizes stacked and leaning: a big green box with a red ribbon at the bottom, a blue one with silver stripes, a tall purple one, a small yellow cube and a tiny pink box on top. Every box has a crossed ribbon and a little bow in a contrasting color.
// Five cheerful, slightly staggered presents.
function gift(x0, y0, z0, x1, y1, z1, paper, ribbon, spots, bowSize) {
const cx = Math.floor((x0 + x1) / 2);
const cy = Math.floor((y0 + y1) / 2);
const midZ = z0 + Math.floor((z1 - z0) * 0.53);
const band = (x1 - x0 > 20) ? 3 : (x1 - x0 > 8 ? 2 : 1);
// Solid wrapping paper, with soft-looking corners and lighter upper faces.
for (let x = x0; x <= x1; x++)
for (let y = y0; y <= y1; y++)
for (let z = z0; z <= z1; z++) {
const corner = (x === x0 || x === x1) && (y === y0 || y === y1);
if (corner && (z === z0 || z === z1)) continue;
let color = paper[0];
if (z === z1) color = paper[1];
else if (x === x1 || y === y1) color = paper[2];
else if (y === y0 || x === x0) color = paper[0];
if (z !== z0 && z !== z1 && rand() < 0.035) color = paper[1];
set(x, y, z, color);
}
// Sparse printed confetti, kept clear of the ribbon.
for (let x = x0 + 2; x <= x1 - 2; x++)
for (let z = z0 + 2; z <= z1 - 2; z++)
if (Math.abs(x - cx) > band + 2 && Math.abs(z - midZ) > 2 &&
rand() < 0.075) set(x, y0, z, spots);
// Crossed ribbon: it runs down both visible sides and across the lid.
for (let x = x0; x <= x1; x++)
for (let y = y0; y <= y1; y++) {
if (Math.abs(x - cx) < band || Math.abs(y - cy) < band)
set(x, y, z1, ribbon[1]);
}
for (let z = z0; z <= z1; z++) {
for (let x = x0; x <= x1; x++) {
if (Math.abs(x - cx) < band || Math.abs(z - midZ) < band)
set(x, y0, z, ribbon[z === z1 ? 1 : 0]);
}
for (let y = y0; y <= y1; y++) {
if (Math.abs(y - cy) < band || Math.abs(z - midZ) < band)
set(x1, y, z, ribbon[2]);
}
}
// Bright narrow highlights make the ribbons look shiny.
for (let z = z0 + 1; z < z1; z++) {
if (Math.abs(z - midZ) >= band) set(cx - 1, y0 - 1, z, ribbon[1]);
}
for (let y = y0 + 1; y < y1; y++) set(cx - 1, y, z1 + 1, ribbon[1]);
for (let x = x0 + 1; x < x1; x++) set(x, cy - 1, z1 + 1, ribbon[1]);
// A bow sits just in front of the lid, where the next present cannot hide it.
const by = y0 - 2;
const bz = z1;
const w = bowSize;
const h = Math.min(bowSize, z1 >= 44 ? 1 : 3);
for (const side of [-1, 1]) {
line(cx, by, bz + 1, cx + side * w, by, bz + h, 0, ribbon[2]);
line(cx + side * w, by, bz + h, cx + side * (w + 1), by, bz + 1, 0, ribbon[1]);
line(cx + side * (w + 1), by, bz + 1, cx, by, bz, 0, ribbon[0]);
if (w > 2) {
line(cx + side, by - 1, bz + 1,
cx + side * (w - 1), by - 1, bz + h, 0, ribbon[1]);
}
line(cx, by, bz, cx + side * Math.max(1, w - 1), by, bz - 2, 0, ribbon[0]);
}
box(cx - 1, by - 1, bz, cx + 1, by, bz + 1, ribbon[1]);
set(cx, by - 2, bz + 1, spots);
}
gift(7, 9, 0, 39, 38, 10,
["#28b95a", "#65e984", "#188e49"],
["#d92739", "#ff6262", "#ab2037"], "#b9ffc5", 4);
gift(11, 11, 11, 34, 33, 20,
["#308cde", "#76c5ff", "#2464b4"],
["#bccbd8", "#ffffff", "#829eaf"], "#d7efff", 3);
gift(20, 14, 21, 30, 25, 32,
["#9254cb", "#c59aee", "#693ea4"],
["#e6a92f", "#ffe477", "#b97b22"], "#f4d9ff", 3);
gift(17, 13, 33, 24, 20, 39,
["#f6d54a", "#fff18d", "#d6a832"],
["#26bdbd", "#8cf5e2", "#168c99"], "#fff8cc", 2);
gift(21, 15, 40, 26, 20, 44,
["#f28fba", "#ffd0df", "#d56b9d"],
["#54cba1", "#b9ffce", "#309878"], "#ffffff", 2);import { draw } from "./assets/voxel";
import { pilaDeRegalos } from "./assets/pila-de-regalos";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, pilaDeRegalos, 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 pila-de-regalos
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["pila-de-regalos"] })
# It lands in client/assets/pila-de-regalos.ts
# https://fogon.page/object/pila-de-regalos