fogón

← Fantasy3D assetfogon/fantasma

Fantasma

by fogonCC010619 blocks
FantasmaDrag to turn it
// «Fantasma» · gpt-6-sol (medium)
// A cute cartoon ghost: a tall rounded white sheet body with a dome head, the bottom edge wavy with three or four pointed tails, two little stubby arms raised as if saying boo, big oval black eyes and a small round open mouth, pale blue-lilac shading on the lower side. It floats a few blocks above a small grey shadow ellipse on the floor.

// A soft shadow anchors the floating ghost.
for (let x = 10; x <= 38; x++) {
  for (let y = 17; y <= 31; y++) {
    const d = ((x - 24) / 14) ** 2 + ((y - 24) / 7) ** 2;
    if (d <= 1) {
      const color = d > 0.78 ? "#b9b4c3" : d > 0.38 ? "#9690a2" : "#777185";
      set(x, y, 0, color);
    }
  }
}

part("ghost", [24, 24, 24]);
animate("ghost", { type: "bob", axis: "z", speed: 2, amplitude: 2 });

function sheetColor(x, y, z, edge) {
  let color;
  if (z < 12) color = "#c3c7e8";
  else if (z < 18) color = "#cdd0ec";
  else if (z < 23) color = "#e2e1f3";
  else color = "#f8f7ff";

  if (edge && (x < 15 || x > 33 || y > 29)) {
    color = z < 23 ? "#bdc4e6" : "#e6e5f4";
  } else if (y <= 19 && z >= 24) {
    color = "#ffffff";
  }

  if (rand() < 0.035) {
    color = z < 23 ? "#dadcf0" : "#f0effa";
  }
  return color;
}

// Four tapered points make a gently scalloped, wavy sheet hem.
for (const [tipX, tipZ] of [[13, 8], [20, 7], [28, 7], [35, 8]]) {
  for (let z = tipZ; z <= 15; z++) {
    const t = (z - tipZ) / (15 - tipZ);
    const rx = 0.8 + 2.9 * t;
    const ry = 1.5 + 6.3 * t;
    for (let x = Math.floor(tipX - rx); x <= Math.ceil(tipX + rx); x++) {
      for (let y = Math.floor(24 - ry); y <= Math.ceil(24 + ry); y++) {
        const d = ((x - tipX) / rx) ** 2 + ((y - 24) / ry) ** 2;
        if (d <= 1) set(x, y, z, sheetColor(x, y, z, d > 0.65));
      }
    }
  }
}

// Broad sheet body and smoothly domed head.
for (let z = 14; z <= 42; z++) {
  const dome = z > 30 ? Math.sqrt(Math.max(0, 1 - ((z - 30) / 13) ** 2)) : 1;
  const rx = 12.8 * dome;
  const ry = 8.5 * dome;
  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) set(x, y, z, sheetColor(x, y, z, d > 0.72));
    }
  }
}

// Little raised, rounded "boo!" arms.
for (const side of [-1, 1]) {
  ellipsoid(24 + side * 12, 24, 26, 4.3, 3.4, 3.7, "#e9e8f6");
  ellipsoid(24 + side * 15, 23, 29, 4.2, 3.5, 3.7, "#f8f7ff");
  sphere(24 + side * 17, 23, 31, 3.1, "#ffffff");
  ellipsoid(24 + side * 15, 21, 32, 2.2, 1, 1.1, "#ffffff");
}

// Big ink-dark eyes, tiny glints, and a surprised open mouth.
for (const eyeX of [19, 29]) {
  ellipsoid(eyeX, 15.7, 31, 2.8, 1.5, 4, "#dedbeb");
  ellipsoid(eyeX, 14.8, 31, 2.35, 1.65, 3.5, "#242033");
  sphere(eyeX - 0.7, 12.9, 32.7, 0.85, "#ffffff");
  set(eyeX + 1, 13, 29, "#77728b");
}

ellipsoid(24, 15.6, 23, 2.5, 1.3, 2.7, "#d8cce6");
ellipsoid(24, 14.7, 23, 1.85, 1.45, 2, "#34283e");
set(24, 13, 22, "#8d6a91");

ellipsoid(15.5, 17.2, 25, 1.7, 0.8, 0.9, "#f1dbea");
ellipsoid(32.5, 17.2, 25, 1.7, 0.8, 0.9, "#f1dbea");