← Antiguo y prehistoriaObjeto 3Dfogon/fogata
Fogata
Arrastrá para girarlo// «Fogata» · gpt-6-sol (medium)
// A campfire: a ring of round grey stones on the ground with crossed dark brown logs in the middle, and a tall cartoon flame rising from them in layers (deep red at the bottom, orange, then yellow at the tips). A few small embers around the logs.
// Campfire stones
const cx = 24, cy = 24;
const greys = ["#666963", "#777b72", "#898d83", "#9ca096"];
for (let i = 0; i < 14; i++) {
const a = 2 * Math.PI * i / 14;
const r = 17 + (rand() - 0.5) * 1.4;
const x = cx + Math.cos(a) * r;
const y = cy + Math.sin(a) * r;
const size = 2.8 + rand() * 0.6;
ellipsoid(x, y, 2, size, size * 0.9, 2.7, greys[i % 3]);
}
// Subtle mottling on the round stones
forEach((x, y, z, color) => {
if (color && z >= 2 && rand() < 0.13) {
set(x, y, z, greys[Math.floor(rand() * greys.length)]);
}
});
// Ash and glowing coals inside the ring
for (let i = 0; i < 32; i++) {
const a = rand() * Math.PI * 2;
const r = 4 + rand() * 10;
const x = Math.round(cx + Math.cos(a) * r);
const y = Math.round(cy + Math.sin(a) * r);
box(x, y, 0, x + (rand() < 0.25 ? 1 : 0), y, 0,
rand() < 0.7 ? "#51443b" : "#70584a");
}
for (let i = 0; i < 16; i++) {
const a = rand() * Math.PI * 2;
const r = 5 + rand() * 8;
const x = Math.round(cx + Math.cos(a) * r);
const y = Math.round(cy + Math.sin(a) * r);
set(x, y, 1 + Math.floor(rand() * 2),
["#a43520", "#dd5a1e", "#f59229", "#ffd063"][i % 4]);
}
// Two chunky crossed logs, with bark grooves and pale cut ends
function log(x0, y0, z0, x1, y1, z1) {
line(x0, y0, z0, x1, y1, z1, 2.8, "#382720");
line(x0, y0, z0 + 1, x1, y1, z1 + 1, 1.8, "#63402b");
line(x0 + 2, y0, z0 + 2, x1 - 2, y1, z1 + 2, 0, "#91603a");
line(x0 + 4, y0 - 1, z0 + 2, x1 - 3, y1 - 1, z1 + 2, 0, "#4b3024");
sphere(x0, y0, z0, 2.1, "#b38553");
sphere(x1, y1, z1, 2.1, "#a97648");
set(x0, y0, z0, "#69472e");
set(x1, y1, z1, "#69472e");
}
log(12, 15, 5, 36, 33, 5);
log(12, 33, 7, 36, 15, 7);
// All flame blocks belong to one animated part.
part("flame", [24, 24, 9]);
function flameShade(z, bottom, top, edge) {
const t = (z - bottom) / (top - bottom);
if (t < 0.23) return edge ? "#ad2e20" : "#c83b20";
if (t < 0.62) return edge ? "#e45a20" : "#f48122";
if (t < 0.88) return edge ? "#ffad30" : "#ffce43";
return edge ? "#ffdb65" : "#fff0a0";
}
// A tapered, slightly bending tongue built from solid elliptical slices
function tongue(x0, y0, bottom, top, width, depth, bend) {
for (let z = bottom; z <= top; z++) {
const t = (z - bottom) / (top - bottom);
const flare = t < 0.19 ? 0.48 + t * 2.7 : Math.pow(1 - t, 0.78);
const rx = Math.max(0.65, width * flare);
const ry = Math.max(0.65, depth * flare);
const mx = x0 + bend * t * t + Math.sin(z * 0.38) * 0.55;
const my = y0 + Math.sin(z * 0.23) * 0.35;
for (let x = Math.floor(mx - rx); x <= Math.ceil(mx + rx); x++) {
for (let y = Math.floor(my - ry); y <= Math.ceil(my + ry); y++) {
const d = ((x - mx) / rx) ** 2 + ((y - my) / ry) ** 2;
if (d <= 1) {
set(x, y, z, flameShade(z, bottom, top, d > 0.72));
}
}
}
}
}
// Side licks frame a taller central flame.
tongue(18, 23, 10, 30, 4.6, 3.5, -3);
tongue(30, 24, 10, 34, 5.0, 3.8, 3);
tongue(24, 24, 9, 40, 7.2, 5.7, -1.2);
// Bright, readable heart on the front of the fire
for (let z = 14; z <= 32; z++) {
const t = (z - 14) / 18;
const radius = (1 - t) * 3.3 + 0.6;
const mid = 24 + Math.sin(z * 0.32) * 0.7;
for (let x = Math.ceil(mid - radius); x <= Math.floor(mid + radius); x++) {
const y = z < 23 ? 18 : 20;
set(x, y, z, z < 19 ? "#f88826" : z < 28 ? "#ffd044" : "#fff0a0");
}
}
animate("flame", {
type: "colors",
palette: ["#b72f20", "#ef6c21", "#ffc038", "#fff0a0"],
pattern: "flicker",
glow: 0.8
});
animate("flame", { type: "bob", axis: "z", amplitude: 1, speed: 4 });
part("body");import { draw } from "./assets/voxel";
import { fogata } from "./assets/fogata";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, fogata, 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 fogata
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["fogata"] })
# Queda en client/assets/fogata.ts
# https://fogon.page/object/fogata