fogón

← Monsters and enemies3D assetfogon/hongo-malvado

Hongo malvado

by fogonCC019570 blocks
Hongo malvadoDrag to turn it
// «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");