← BásicoObjeto 3Dfogon/lampara-de-aceite
Lámpara de aceite
Arrastrá para girarlo// «Lámpara de aceite» · gpt-6-sol (medium)
// Oil lamp («Lámpara de aceite»). Be faithful to the reference: keep thin parts thin (1–2 blocks: strings, necks, handles, legs, rods), keep its exact proportions and silhouette, and every visible detail (books on shelves, sound holes, tuning pegs, valves). Don't make it chunkier than the reference.
const gold = {
light: "#f4cc73", top: "#ffe09a", mid: "#dca74d",
side: "#ba7b2d", shade: "#87531f", groove: "#70441f"
};
const steel = {
light: "#e1eeee", mid: "#a9c2c3",
shade: "#66878a", dark: "#365e65"
};
const cx = 24, cy = 24;
// Squat, rounded oil reservoir, built in stepped brass courses.
const radii = [
9, 12, 14, 14, 13, 12, 13, 14, 15, 16,
17, 17, 17, 16, 15, 14, 12, 10, 8
];
const raised = new Set([1, 3, 7, 10, 12, 15]);
for (let z = 0; z < radii.length; z++) {
const radius = radii[z];
for (let x = 5; x <= 43; x++) {
for (let y = 6; y <= 42; y++) {
const dx = x - cx, dy = (y - cy) / 0.91;
const angle = Math.atan2(dy, dx);
const scallop = 0.34 * Math.cos(angle * 20);
const d = Math.hypot(dx, dy);
if (d > radius + scallop) continue;
const edge = d > radius - 1.5;
const exposedTop = z === 18 || d > (radii[z + 1] || 0) + 0.2;
let color;
if (exposedTop) color = rand() < 0.19 ? gold.light : gold.top;
else if (edge && [4, 6, 8, 13, 16].includes(z))
color = rand() < 0.22 ? gold.side : gold.shade;
else if (edge && raised.has(z))
color = rand() < 0.23 ? gold.top : gold.light;
else if (edge)
color = rand() < 0.18 ? gold.shade : gold.mid;
else
color = gold.mid;
if (edge && y > 28 && !exposedTop && rand() < 0.31)
color = gold.side;
set(x, y, z, color);
}
}
}
// Fine, staggered beading along the ornamental bands.
for (const z of [2, 7, 10, 12, 15]) {
for (let i = 0; i < 56; i++) {
const a = i * Math.PI * 2 / 56;
const r = radii[z] + (i % 3 === 0 ? 0.35 : -0.35);
const x = Math.round(cx + Math.cos(a) * r);
const y = Math.round(cy + Math.sin(a) * r * 0.91);
set(x, y, z, i % 5 === 0 ? "#fff0ac" : gold.light);
}
}
// Dark seams between courses on the visible front.
for (const z of [4, 8, 13]) {
for (let x = 12; x <= 36; x++) {
const dx = x - cx;
const r = radii[z];
if (Math.abs(dx) >= r) continue;
const y = Math.round(cy - Math.sqrt(r * r - dx * dx) * 0.91);
if (rand() < 0.74) set(x, y, z, gold.groove);
}
}
// Narrow shoulder and burner seat.
cylinder(24, 24, 18, 9, 2, gold.side);
cylinder(24, 24, 19, 8, 1, gold.light);
cylinder(24, 24, 20, 7, 1, "#52747a");
cylinder(24, 24, 21, 6, 1, steel.mid);
cylinder(24, 24, 22, 5, 1, steel.dark);
cylinder(24, 24, 22, 3, 1, "#302d24");
// Silver lip, with the darker recess visible around the wick.
for (let i = 0; i < 36; i++) {
const a = i * Math.PI * 2 / 36;
set(Math.round(24 + 6 * Math.cos(a)),
Math.round(24 + 6 * Math.sin(a)), 22,
i % 4 === 0 ? steel.light : steel.mid);
}
// Small brass adjuster projecting from the right.
box(32, 23, 18, 36, 25, 20, gold.mid);
box(36, 22, 18, 39, 26, 21, gold.side);
box(38, 23, 19, 40, 25, 20, gold.light);
box(39, 23, 18, 40, 25, 18, gold.shade);
// Wick and its small, bright tapered flame.
box(23, 23, 23, 25, 25, 24, "#855020");
box(22, 23, 25, 26, 25, 26, "#c66b19");
box(23, 23, 27, 26, 25, 28, "#ea9b20");
box(24, 23, 29, 25, 24, 30, "#ffd453");
set(24, 23, 31, "#ffe788");
box(24, 22, 25, 25, 22, 27, "#ffcb37");
box(24, 22, 27, 24, 22, 29, "#fff1a0");
set(22, 23, 25, "#f2a624");
set(26, 24, 27, "#ffe078");
// Open, slender chimney frame: four upright strips, not solid glass.
box(17, 18, 29, 18, 19, 41, steel.dark);
box(18, 18, 30, 18, 18, 40, steel.mid);
box(17, 29, 29, 18, 30, 41, steel.shade);
box(18, 29, 30, 18, 29, 40, steel.light);
box(30, 19, 25, 31, 20, 41, steel.shade);
box(31, 19, 26, 31, 19, 40, steel.light);
box(30, 29, 23, 31, 30, 41, steel.mid);
box(31, 29, 24, 31, 29, 40, steel.light);
// One front upright curves outward into the lower burner guard.
line(17, 18, 29, 13, 18, 26, 0, steel.mid);
line(13, 18, 26, 13, 18, 22, 0, steel.shade);
line(14, 18, 22, 17, 18, 20, 0, steel.mid);
box(12, 18, 23, 13, 19, 26, steel.shade);
box(13, 17, 23, 13, 17, 25, steel.light);
line(17, 18, 20, 20, 18, 20, 0, steel.light);
// Right-hand lower support and its bright edge.
line(31, 29, 23, 34, 28, 21, 0, steel.shade);
line(31, 19, 25, 33, 19, 22, 0, steel.light);
box(32, 18, 20, 33, 19, 22, steel.mid);
set(33, 18, 21, steel.light);
// Square, hollow cap at the top of the chimney.
box(16, 17, 42, 32, 18, 43, steel.mid);
box(16, 29, 42, 32, 30, 43, steel.light);
box(16, 18, 42, 17, 29, 43, steel.shade);
box(31, 18, 42, 32, 29, 43, steel.light);
box(18, 19, 42, 30, 28, 42, "#42666b");
box(20, 21, 43, 28, 26, 43, "#34565a");
box(16, 17, 44, 31, 17, 44, "#f0f2e9");
box(16, 18, 44, 17, 29, 44, "#d6e1dd");
box(18, 29, 44, 32, 29, 44, "#f1f1e5");
box(32, 18, 44, 32, 28, 44, "#edf0e7");import { draw } from "./assets/voxel";
import { lamparaDeAceite } from "./assets/lampara-de-aceite";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, lamparaDeAceite, 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 lampara-de-aceite
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["lampara-de-aceite"] })
# Queda en client/assets/lampara-de-aceite.ts
# https://fogon.page/object/lampara-de-aceite