← Piezas de nivel 2Objeto 3Dfogon/nivel-diamante
Diamante
Arrastrá para girarlo// «Diamante» · gpt-6-sol (medium)
// A big brilliant-cut diamond collectible: a wide flat top table and crown and a long pointed pavilion below, about 30 wide and 28 tall, pale cyan and white in 4 shades with bright white facet edges and sparkles, floating with its point at z 4.
// A small glint touches the floor while the diamond floats above it.
set(24, 24, 0, "#f7ffff");
set(23, 24, 0, "#dcf8ff");
set(25, 24, 0, "#dcf8ff");
set(24, 23, 0, "#dcf8ff");
set(24, 25, 0, "#dcf8ff");
part("diamante", [24, 24, 18]);
const shades = ["#f7ffff", "#dcf8ff", "#a9e9f5", "#78d2e9"];
const cx = 24, cy = 24;
const tau = Math.PI * 2;
function profile(z) {
if (z <= 20) {
const t = (z - 4) / 16;
return [0.6 + 14.4 * t, 0.4 + 5.6 * t];
}
const t = Math.min(1, (z - 20) / 11);
return [15 - 6 * t, 6 - 2 * t];
}
for (let z = 4; z <= 32; z++) {
const [radius, corner] = profile(z);
for (let x = 8; x <= 40; x++) {
for (let y = 8; y <= 40; y++) {
const dx = x - cx, dy = y - cy;
if (
Math.abs(dx) > radius ||
Math.abs(dy) > radius ||
Math.abs(dx) + Math.abs(dy) > radius + corner
) continue;
let color;
if (z === 32) {
color = dx < 0 || dy < 0 ? shades[0] : shades[1];
} else {
const angle = (Math.atan2(dy, dx) + tau) % tau;
const facet = Math.floor((angle + Math.PI / 8) / (Math.PI / 4)) % 8;
if (z >= 20) {
color = shades[[2, 1, 2, 3, 2, 1, 1, 0][facet]];
if (z >= 29 && facet % 2 === 1) color = shades[1];
} else {
color = shades[[2, 1, 2, 3, 3, 2, 1, 1][facet]];
if ((facet === 1 || facet === 6) && z < 13) color = shades[2];
if (facet === 3 && z < 12) color = shades[2];
}
}
set(x, y, z, color);
}
}
}
// White edges outline the table, crown, and pointed pavilion.
const outer = [
[-15, -6], [-6, -15], [6, -15], [15, -6],
[15, 6], [6, 15], [-6, 15], [-15, 6]
];
const table = [
[-9, -4], [-4, -9], [4, -9], [9, -4],
[9, 4], [4, 9], [-4, 9], [-9, 4]
];
for (let i = 0; i < 8; i++) {
const j = (i + 1) % 8;
const a = outer[i], b = outer[j];
const c = table[i], d = table[j];
line(cx + a[0], cy + a[1], 20, cx + b[0], cy + b[1], 20, 0, shades[0]);
line(cx + c[0], cy + c[1], 32, cx + d[0], cy + d[1], 32, 0, shades[0]);
line(cx + a[0], cy + a[1], 20, cx + c[0], cy + c[1], 31, 0,
i % 3 === 0 ? shades[0] : shades[1]);
line(cx + a[0], cy + a[1], 20, cx, cy, 4, 0,
i % 2 === 0 ? shades[1] : shades[2]);
}
// Small star glints on the viewer-facing surface.
function sparkle(x, z, size) {
let front;
for (let y = 8; y <= 24; y++) {
if (get(x, y, z)) {
front = y;
break;
}
}
if (front === undefined) return;
const y = front - 1;
set(x, y, z, shades[0]);
for (let d = 1; d <= size; d++) {
set(x - d, y, z, shades[0]);
set(x + d, y, z, shades[0]);
set(x, y, z - d, shades[0]);
set(x, y, z + d, shades[0]);
}
}
sparkle(19, 27, 2);
sparkle(30, 23, 1);
sparkle(25, 15, 1);
animate("diamante", { type: "spin", axis: "z", speed: -2 });
animate("diamante", { type: "bob", axis: "z", amplitude: 1.5 });import { draw } from "./assets/voxel";
import { nivelDiamante } from "./assets/nivel-diamante";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, nivelDiamante, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add nivel-diamante
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["nivel-diamante"] })
# Queda en client/assets/nivel-diamante.ts
# https://fogon.page/object/nivel-diamante