← FantasíaObjeto 3Dfogon/ent
Ent
Arrastrá para girarlo// «Ent» · gpt-6-sol (medium)
// A friendly walking tree giant (ent) facing front (-y): a thick brown bark trunk as the body with a kind face carved in it (glowing amber eyes, mossy beard), two branch arms with small leafy clumps, two root legs, and a bushy green leaf crown on top with a little bird nest.
// Friendly walking tree giant
const bark = "#705039", barkLight = "#936b46", barkDark = "#493629";
const leaf = "#397c48", leafLight = "#68a85a", leafDark = "#285b42";
const moss = "#70a84a", amber = "#ffc66b";
function twig(x0, y0, z0, x1, y1, z1, r = 1) {
line(x0, y0, z0, x1, y1, z1, r, barkDark);
}
// Solid, rounded trunk with a broad chest and narrower waist.
ellipsoid(24, 25, 21, 9, 8, 13, bark);
ellipsoid(24, 25, 15, 8, 7, 7, barkDark);
ellipsoid(24, 24, 27, 9, 8, 8, bark);
ellipsoid(24, 17, 26, 7, 2, 8, barkLight);
// Bark grain and small highlights on the visible front.
for (let i = 0; i < 65; i++) {
const x = 17 + Math.floor(rand() * 15);
const z = 14 + Math.floor(rand() * 21);
for (let y = 13; y <= 20; y++) {
if (get(x, y, z) && !get(x, y - 1, z)) {
set(x, y, z, rand() < 0.7 ? barkLight : barkDark);
break;
}
}
}
line(17, 19, 19, 18, 18, 28, 0, barkDark);
line(31, 19, 18, 30, 18, 27, 0, barkDark);
line(21, 17, 33, 20, 16, 35, 0, barkDark);
// Warm, kind face.
ellipsoid(20, 14, 28, 2, 1, 2, barkDark);
ellipsoid(28, 14, 28, 2, 1, 2, barkDark);
sphere(20, 13, 28, 1, amber);
sphere(28, 13, 28, 1, amber);
set(20, 12, 29, "#fff0ab");
set(28, 12, 29, "#fff0ab");
line(18, 14, 31, 21, 14, 32, 1, barkDark);
line(27, 14, 32, 30, 14, 31, 1, barkDark);
ellipsoid(24, 13, 24, 2, 2, 2, barkLight);
set(24, 11, 24, "#b88a54");
line(20, 14, 21, 22, 13, 20, 0, barkDark);
line(22, 13, 20, 26, 13, 20, 0, barkDark);
line(26, 13, 20, 28, 14, 21, 0, barkDark);
// Soft, scalloped moss beard beneath the smile.
for (let x = 19; x <= 29; x += 2) {
const tip = 14 + Math.floor(rand() * 3);
ellipsoid(x, 15, 18, 2, 2, 2, leafDark);
line(x, 14, 18, x + (x < 24 ? 1 : -1), 15, tip, 1,
rand() < 0.5 ? moss : leaf);
}
sphere(19, 14, 18, 1, leafLight);
sphere(28, 14, 17, 1, leafLight);
// Bushy crown: darker undergrowth, then overlapping sunlit leaf pillows.
ellipsoid(24, 26, 36, 14, 10, 7, leafDark);
ellipsoid(24, 26, 39, 13, 10, 6, leaf);
[
[13, 25, 37, 5, 6, 5], [17, 19, 40, 6, 5, 5],
[25, 19, 41, 7, 5, 5], [33, 21, 39, 6, 6, 5],
[36, 29, 38, 5, 6, 5], [27, 32, 41, 8, 6, 4],
[18, 32, 40, 6, 6, 5], [24, 26, 43, 8, 7, 3]
].forEach(([x, y, z, rx, ry, rz], i) =>
ellipsoid(x, y, z, rx, ry, rz, i % 3 === 0 ? leafLight : leaf)
);
for (let i = 0; i < 85; i++) {
const x = 10 + Math.floor(rand() * 29);
const y = 17 + Math.floor(rand() * 19);
const z = 35 + Math.floor(rand() * 11);
if (get(x, y, z) && !get(x, y - 1, z))
set(x, y, z, rand() < 0.65 ? leafLight : "#8bbd64");
}
// Little nest tucked into the front-right leaves, with a tiny blue bird.
ellipsoid(31, 16, 38, 5, 3, 2, barkDark);
ellipsoid(31, 15, 39, 4, 2, 1, "#aa7847");
for (let i = 0; i < 13; i++) {
const a = i * Math.PI * 2 / 13;
const x = 31 + Math.round(4 * Math.cos(a));
const y = 16 + Math.round(2 * Math.sin(a));
twig(x - 1, y, 39, x + 1, y - 1, 40, 0);
}
ellipsoid(31, 15, 41, 2, 2, 2, "#42b4a8");
sphere(32, 14, 42, 1, "#78ddc5");
set(32, 13, 42, "#162d31");
set(34, 14, 41, "#ffc66b");
// Root legs pivot at the hips and swing gently as the ent walks.
part("left root leg", [20, 25, 13]);
line(20, 25, 13, 18, 24, 4, 3, barkDark);
ellipsoid(18, 21, 2, 4, 6, 2, bark);
line(17, 18, 2, 15, 16, 0, 1, barkLight);
line(19, 18, 2, 20, 15, 0, 1, barkLight);
animate("left root leg", { type: "swing", axis: "x", speed: 2, amplitude: 0.2 });
part("right root leg", [28, 25, 13]);
line(28, 25, 13, 30, 24, 4, 3, barkDark);
ellipsoid(30, 21, 2, 4, 6, 2, bark);
line(29, 18, 2, 28, 15, 0, 1, barkLight);
line(32, 18, 2, 34, 16, 0, 1, barkLight);
animate("right root leg", { type: "swing", axis: "x", speed: -2, amplitude: 0.2 });
// Branch arms, each with little leafy hands.
part("left branch arm", [16, 25, 29]);
line(16, 25, 29, 10, 24, 25, 2, bark);
line(10, 24, 25, 5, 22, 22, 2, barkDark);
twig(7, 23, 23, 5, 21, 27);
twig(6, 22, 22, 4, 20, 20);
ellipsoid(5, 21, 26, 3, 3, 3, leaf);
sphere(4, 20, 27, 2, leafLight);
ellipsoid(5, 20, 20, 2, 2, 2, leafLight);
animate("left branch arm", { type: "swing", axis: "x", speed: 1.5, amplitude: 0.3 });
part("right branch arm", [32, 25, 29]);
line(32, 25, 29, 38, 24, 25, 2, bark);
line(38, 24, 25, 43, 22, 22, 2, barkDark);
twig(41, 23, 23, 43, 21, 27);
twig(42, 22, 22, 44, 20, 20);
ellipsoid(43, 21, 26, 3, 3, 3, leaf);
sphere(44, 20, 27, 2, leafLight);
ellipsoid(43, 20, 20, 2, 2, 2, leafLight);
animate("right branch arm", { type: "swing", axis: "x", speed: -1.5, amplitude: 0.3 });
part("body");import { draw } from "./assets/voxel";
import { ent } from "./assets/ent";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, ent, 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 ent
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["ent"] })
# Queda en client/assets/ent.ts
# https://fogon.page/object/ent