← Monstruos y enemigosObjeto 3Dfogon/hongo-malvado
Hongo malvado
Arrastrá para girarlo// «Hongo malvado» · gpt-6-sol (medium)
// A cartoon evil mushroom creature facing -y: a big red cap with white spots, a cream stem body with an angry face (frowning eyebrows, glowing yellow eyes, jagged grin), two little stubby arms and two short feet.
// Cream stem body: broad at the base, tucked beneath the cap.
for (let z = 5; z <= 28; z++) {
const taper = Math.sqrt(Math.max(0, 1 - ((z - 16.5) / 12.5) ** 2));
const rx = 7.5 + 2.5 * taper;
const ry = 7 + 2.5 * taper;
for (let x = 13; x <= 35; x++) {
for (let y = 13; y <= 35; y++) {
if (((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2 > 1) continue;
let c = "#e8d6a6";
if (z < 11 || y > 28) c = "#bda875";
else if (y < 20 && z > 12) c = "#f7e9bd";
if (rand() < 0.055) c = y < 22 ? "#fff1ca" : "#d4bf8d";
set(x, y, z, c);
}
}
}
// Find the visible front of the stem for crisp, readable facial features.
function front(x, z) {
for (let y = 8; y <= 25; y++) if (get(x, y, z)) return y;
return 16;
}
function face(x, z, color, depth = 1) {
set(x, front(x, z) - depth, z, color);
}
// Short arms and mitten-like hands.
for (const side of [-1, 1]) {
const sx = 24 + side * 10;
ellipsoid(sx + side * 2, 24, 14, 4, 4, 4, "#bba477");
ellipsoid(sx + side * 3, 21, 14, 3, 4, 3, "#ead6a5");
ellipsoid(sx + side * 4, 19, 12, 3, 3, 3, "#f5e5b8");
box(sx + side * 3 - 1, 17, 10, sx + side * 3 + 1, 19, 11, "#d7bf8f");
}
// Recessed eye sockets.
for (const [a, b] of [[17, 21], [27, 31]]) {
for (let x = a; x <= b; x++) {
for (let z = 17; z <= 20; z++) {
face(x, z, z === 17 || x === a || x === b ? "#574337" : "#302d34");
}
}
}
// Bright eyes, with a pale central glint.
for (const [a, b] of [[18, 20], [28, 30]]) {
for (let x = a; x <= b; x++) {
for (let z = 18; z <= 19; z++) face(x, z, "#ffc727", 2);
}
face(a + 1, 19, "#fff68b", 3);
face(a + 1, 18, "#ffe34d", 3);
}
// Brows slant down toward the middle.
for (let x = 16; x <= 22; x++) {
const z = x <= 18 ? 23 : x <= 20 ? 22 : 21;
face(x, z, "#574139", 2);
face(x, z + 1, "#76523c");
}
for (let x = 26; x <= 32; x++) {
const z = x >= 30 ? 23 : x >= 28 ? 22 : 21;
face(x, z, "#574139", 2);
face(x, z + 1, "#76523c");
}
// Crooked, jagged grin.
for (let x = 18; x <= 30; x++) {
const lower = 11 + Math.floor(Math.abs(x - 24) * 0.42);
for (let z = lower; z <= 14; z++) face(x, z, "#493b39", 2);
if (x > 18 && x < 30 && x % 3 !== 0) {
face(x, 14, "#fff0ca", 3);
if (x % 4 === 0) face(x, 13, "#fff0ca", 3);
}
}
face(18, 15, "#775345", 2);
face(30, 15, "#775345", 2);
// Little feet swing independently from their hips.
for (const [name, cx, speed] of [
["leftLeg", 18, 5],
["rightLeg", 30, -5]
]) {
part(name, [cx, 24, 9]);
ellipsoid(cx, 24, 7, 3, 4, 4, "#c7af7e");
ellipsoid(cx, 20, 3, 5, 6, 3, "#b79d6f");
ellipsoid(cx, 18, 3, 4, 4, 2, "#ead5a3");
box(cx - 3, 15, 0, cx + 3, 21, 1, "#947d5c");
for (let dx of [-2, 1]) {
box(cx + dx, 14, 2, cx + dx + 1, 16, 3, "#f7e5b9");
}
animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });
}
part("body");
// Broad red mushroom cap, with a dark underside and chunky rolled rim.
part("cap", [24, 24, 25]);
const layers = {
23: 10, 24: 15, 25: 18, 26: 20, 27: 20,
28: 20, 29: 19, 30: 19, 31: 18, 32: 18,
33: 17, 34: 16, 35: 15, 36: 13, 37: 11,
38: 8, 39: 5, 40: 2
};
for (let z = 23; z <= 40; z++) {
const rx = layers[z];
const ry = Math.round(rx * 0.94);
for (let x = 24 - rx; x <= 24 + rx; x++) {
for (let y = 24 - ry; y <= 24 + ry; y++) {
const d = ((x - 24) / rx) ** 2 + ((y - 24) / ry) ** 2;
if (d > 1) continue;
let c;
if (z <= 24) c = "#765247";
else if (z <= 26) c = d > 0.72 ? "#962d36" : "#ae5748";
else if (z <= 28) c = "#b82431";
else c = y < 22 || z >= 36 ? "#e64140" : "#ce3038";
if (z >= 29 && d < 0.8 && rand() < 0.055) c = "#ed5147";
set(x, y, z, c);
}
}
}
// Pale spots follow the cap's visible front and upper surface.
const frontSpots = [
[11, 29, 2.6, 2.0], [17, 33, 2.9, 2.3],
[28, 31, 3.1, 2.1], [37, 29, 2.3, 1.8],
[23, 28, 1.7, 1.3]
];
const topSpots = [
[12, 23, 2.8, 2.5], [23, 19, 2.4, 2.0],
[33, 25, 3.0, 2.5], [27, 34, 2.3, 2.0],
[17, 32, 1.8, 1.8]
];
for (let z = 28; z <= 40; z++) {
for (let x = 4; x <= 44; x++) {
for (let y = 5; y <= 43; y++) {
if (!get(x, y, z)) continue;
const visibleFront = y < 21 && !get(x, y - 1, z);
const visibleTop = !get(x, y, z + 1);
let d = 2;
if (visibleFront) {
for (const [sx, sz, rx, rz] of frontSpots)
d = Math.min(d, ((x - sx) / rx) ** 2 + ((z - sz) / rz) ** 2);
}
if (visibleTop) {
for (const [sx, sy, rx, ry] of topSpots)
d = Math.min(d, ((x - sx) / rx) ** 2 + ((y - sy) / ry) ** 2);
}
if (d <= 1) set(x, y, z, d > 0.68 ? "#e9d6bc" : "#fff4dc");
}
}
}
animate("cap", { type: "bob", axis: "z", speed: 3, amplitude: 1 });
part("body");import { draw } from "./assets/voxel";
import { hongoMalvado } from "./assets/hongo-malvado";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, hongoMalvado, 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 hongo-malvado
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["hongo-malvado"] })
# Queda en client/assets/hongo-malvado.ts
# https://fogon.page/object/hongo-malvado