← FantasíaObjeto 3Dfogon/caldero
Caldero
Arrastrá para girarlo// «Caldero» · gpt-6-sol (medium)
// A round black iron witch's cauldron on three short stubby legs, with a thick rim and two side ring handles, over a small campfire of crossed logs with orange flames. It's full to the rim with bubbling bright green brew, with a few round bubbles sticking up from the surface.
// Crossed campfire logs and glowing embers.
const wood = ["#473225", "#59402b", "#6b4b30"];
line(15, 17, 2, 33, 31, 2, 2.2, wood[0]);
line(33, 17, 2, 15, 31, 2, 2.2, wood[1]);
for (let i = 0; i < 16; i++) {
const x = 16 + rand() * 17, y = 17 + rand() * 14;
set(x, y, 4, rand() < 0.6 ? "#db612b" : "#ffb446");
}
// A few mossy stones around the fire.
for (let i = 0; i < 11; i++) {
const a = i * Math.PI * 2 / 11;
const x = 24 + Math.cos(a) * 12;
const y = 24 + Math.sin(a) * 11;
ellipsoid(x, y, 1, 2.2, 1.7, 1.3, i % 3 ? "#696d62" : "#838477");
if (i % 3 === 0) set(x, y, 3, "#78905b");
}
// Three short, splayed iron feet.
for (const [x, y] of [[15, 18], [33, 18], [24, 33]]) {
ellipsoid(x, y, 7, 3.4, 3, 5.5, "#25272d");
ellipsoid(x, y - 0.5, 4, 3.5, 3, 2, "#343840");
box(x - 1, y - 2, 6, x + 1, y - 2, 9, "#484b50");
}
// Solid, round-bellied cauldron, tapering toward its mouth.
for (let z = 10; z <= 30; z++) {
const t = (z - 21) / 13;
const rx = 16 * Math.sqrt(Math.max(0, 1 - t * t));
const ry = 15 * Math.sqrt(Math.max(0, 1 - t * t));
for (let x = Math.floor(24 - rx); x <= Math.ceil(24 + rx); x++)
for (let y = Math.floor(24 - ry); y <= Math.ceil(24 + ry); y++) {
const d = ((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2;
if (d > 1) continue;
let c = "#22242a";
if (y < 19 && z > 15) c = "#363940";
if (y < 15 && z > 19) c = "#41444a";
if (z < 15 || y > 34) c = "#191c22";
if (d > 0.82 && rand() < 0.09) c = "#505157";
set(x, y, z, c);
}
}
// Broad rolled lip: its open center leaves the brew visible.
for (let z = 29; z <= 33; z++)
for (let x = 8; x <= 40; x++)
for (let y = 8; y <= 40; y++) {
const d = Math.hypot(x - 24, y - 24);
const outer = z === 33 ? 14.2 : 15;
if (d >= 11.7 && d <= outer) {
let c = z === 33 ? "#55565b" : "#25272d";
if (y < 22 && z === 33) c = "#707076";
if (z === 29) c = "#17191e";
set(x, y, z, c);
}
}
// Side lugs and chunky, open ring handles.
for (const side of [-1, 1]) {
const cx = 24 + side * 17;
box(24 + side * 11, 20, 25, 24 + side * 14, 23, 29, "#282a30");
set(24 + side * 13, 19, 27, "#af8950");
for (let x = cx - 5; x <= cx + 5; x++)
for (let z = 21; z <= 31; z++) {
const d = Math.hypot(x - cx, z - 26);
if (d >= 3 && d <= 5) {
for (let y = 20; y <= 22; y++)
set(x, y, z, z >= 27 ? "#555258" : "#303036");
}
}
}
// Flickering tongues of fire, tucked beneath the pot.
part("flames", [24, 22, 3]);
for (const [x, y, h, lean] of [
[19, 19, 10, -2], [24, 17, 12, 1], [29, 20, 9, 2],
[22, 24, 8, -1], [27, 24, 7, 1]
]) {
for (let z = 3; z <= h; z++) {
const u = (z - 3) / (h - 2);
const fx = x + lean * u;
const r = Math.max(0.5, 2.6 * (1 - u));
ellipsoid(fx, y, z, r, Math.max(0.5, r * 0.8), 0.8,
u > 0.65 ? "#ffe063" : u > 0.3 ? "#ff9a2f" : "#e94f28");
}
}
animate("flames", {
type: "colors", palette: ["#ff782d", "#ffd049", "#ec4930"],
pattern: "flicker", glow: 0.9
});
// Bright, gently bubbling magical brew.
part("brew", [24, 24, 31]);
for (let x = 12; x <= 36; x++)
for (let y = 12; y <= 36; y++) {
const d = Math.hypot(x - 24, y - 24);
if (d <= 11.5) {
set(x, y, 30, "#4dbd25");
set(x, y, 31, rand() < 0.2 ? "#d4fb4b" : "#75e532");
if (rand() < 0.035) set(x, y, 32, "#dcff72");
}
}
for (const [x, y, z, r] of [
[18, 20, 33, 2], [27, 20, 34, 2.5],
[24, 27, 33, 1.7], [31, 28, 33, 1.5],
[20, 29, 32, 1.2]
]) {
sphere(x, y, z, r, "#a5f83b");
set(x - 1, y - 1, Math.round(z + r), "#e4ff83");
}
animate("brew", {
type: "colors", palette: ["#49cf2a", "#a5f83b", "#d9f347"],
pattern: "noise", glow: 0.7
});import { draw } from "./assets/voxel";
import { caldero } from "./assets/caldero";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, caldero, 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 caldero
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["caldero"] })
# Queda en client/assets/caldero.ts
# https://fogon.page/object/caldero