fogón

← Monstruos y enemigosObjeto 3Dfogon/golem-de-cristal

Gólem de cristal

de fogonCC019942 bloques
Gólem de cristalArrastrá para girarlo
// «Gólem de cristal» · gpt-6-sol (medium)
// A big boss: a towering cartoon crystal golem facing -y: a massive body of chunky faceted purple and magenta crystals with lighter edges, a small head with two glowing white eyes, huge crystal fists, thick legs, and bright glowing crystal clusters growing from the shoulders and back.

const dark = "#35134f";
const shadow = "#552078";
const purple = "#7832a3";
const light = "#a64bd0";
const magenta = "#cf42bd";
const pink = "#f07ad9";
const edge = "#ffd0f5";

function shade(x, y, z, cx, cy, top, colors) {
  if (z >= top - 2 || y <= cy - 5 || x <= cx - 5) return colors[2];
  if (x >= cx + 5 || z < 5) return colors[0];
  return rand() < 0.08 ? colors[2] : colors[1];
}

// Thick, angular legs, animated separately at the hips.
function makeLeg(name, cx, speed) {
  part(name, [cx, 24, 17]);
  for (let z = 0; z <= 18; z++) {
    const rx = z < 5 ? 5 : z < 13 ? 4 : 5;
    const front = z < 5 ? 14 : 18;
    const back = z < 5 ? 29 : 29;
    for (let x = cx - rx; x <= cx + rx; x++)
      for (let y = front; y <= back; y++) {
        if (Math.abs(x - cx) === rx && (y === front || y === back)) continue;
        const c = shade(x, y, z, cx, 24, 18, [dark, shadow, purple]);
        set(x, y, z, c);
      }
  }
  // Wide crystal toes and knee plates.
  box(cx - 4, 13, 1, cx + 4, 17, 4, purple);
  box(cx - 3, 13, 4, cx + 3, 14, 5, light);
  box(cx - 3, 17, 11, cx + 3, 18, 14, light);
  box(cx - 1, 16, 12, cx + 1, 16, 14, pink);
  animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });
}
makeLeg("left leg", 17, 2);
makeLeg("right leg", 31, -2);

part("body", [24, 24, 25]);

// Massive tapered torso with clipped, faceted corners.
for (let z = 15; z <= 35; z++) {
  const rx = z < 19 ? 11 : z < 31 ? 13 : 11;
  const ry = z < 19 ? 8 : z < 31 ? 10 : 8;
  for (let x = 24 - rx; x <= 24 + rx; x++)
    for (let y = 24 - ry; y <= 24 + ry; y++) {
      const dx = Math.abs(x - 24), dy = Math.abs(y - 24);
      if (dx > rx - 3 && dy > ry - 3) continue;
      let c = shade(x, y, z, 24, 24, 35, [shadow, purple, light]);
      if (z <= 17 || (dx >= rx - 1 && y > 24)) c = dark;
      set(x, y, z, c);
    }
}

// Big bright diamond embedded in the chest.
for (let z = 20; z <= 31; z++)
  for (let x = 17; x <= 31; x++) {
    const d = Math.abs(x - 24) / 7 + Math.abs(z - 26) / 6;
    if (d <= 1) set(x, 13, z, d > 0.75 ? pink : magenta);
    if (d <= 0.46) set(x, 12, z, light);
  }
line(24, 11, 22, 24, 11, 29, 0, edge);
box(13, 18, 26, 15, 30, 29, shadow);
box(33, 18, 26, 35, 30, 29, shadow);

// Small angular head, tucked between the enormous shoulders.
for (let z = 33; z <= 43; z++) {
  const rx = z >= 41 ? 6 : 7;
  const ry = z >= 41 ? 5 : 7;
  for (let x = 24 - rx; x <= 24 + rx; x++)
    for (let y = 20 - ry; y <= 20 + ry; y++) {
      if (Math.abs(x - 24) > rx - 2 && Math.abs(y - 20) > ry - 2) continue;
      let c = shade(x, y, z, 24, 20, 43, [dark, purple, light]);
      if (z === 33 || (y >= 25 && z < 37)) c = shadow;
      set(x, y, z, c);
    }
}
box(18, 13, 35, 30, 13, 40, purple);
box(19, 13, 40, 29, 14, 41, light);
box(20, 12, 38, 22, 13, 39, pink);
box(26, 12, 38, 28, 13, 39, pink);
box(20, 11, 38, 22, 11, 39, "#ffffff");
box(26, 11, 38, 28, 11, 39, "#ffffff");
set(21, 10, 39, "#ffffff");
set(27, 10, 39, "#ffffff");
// A tiny, friendly crooked smile.
for (let x = 22; x <= 26; x++) set(x, 12, x === 24 ? 34 : 35, dark);

// Crystal fists and heavy forearms, each hinged at its shoulder.
function makeArm(name, side, speed) {
  const pivot = side < 0 ? 12 : 36;
  const cx = side < 0 ? 8 : 40;
  part(name, [pivot, 24, 32]);
  for (let z = 19; z <= 33; z++) {
    const rx = z < 23 ? 4 : 3;
    for (let x = cx - rx; x <= cx + rx; x++)
      for (let y = 20; y <= 29; y++) {
        if (Math.abs(x - cx) === rx && (y === 20 || y === 29)) continue;
        set(x, y, z, shade(x, y, z, cx, 25, 33,
          [dark, z < 24 ? purple : shadow, light]));
      }
  }
  for (let z = 13; z <= 21; z++)
    for (let x = cx - 5; x <= cx + 5; x++)
      for (let y = 18; y <= 29; y++) {
        if (Math.abs(x - cx) >= 4 && (y <= 19 || y >= 28)) continue;
        set(x, y, z, shade(x, y, z, cx, 24, 21,
          [shadow, purple, light]));
      }
  box(cx - 3, 17, 17, cx + 3, 18, 20, magenta);
  box(cx - 2, 17, 19, cx + 2, 17, 20, pink);
  for (const offset of [-3, 0, 3]) {
    box(cx + offset, 17, 13, cx + offset + 1, 19, 15, dark);
  }
  animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });
}
makeArm("left arm", -1, 2);
makeArm("right arm", 1, -2);

// All glowing shoulder and back crystals share one pulsing color part.
part("crystal clusters", [24, 27, 32]);

function crystal(cx, cy, base, height, rx, ry, leanX, leanY) {
  for (let i = 0; i < height; i++) {
    const t = i / height;
    const xmid = cx + Math.round(leanX * t);
    const ymid = cy + Math.round(leanY * t);
    const w = Math.max(0, Math.round(rx * (1 - t * 0.82)));
    const d = Math.max(0, Math.round(ry * (1 - t * 0.82)));
    for (let x = xmid - w; x <= xmid + w; x++)
      for (let y = ymid - d; y <= ymid + d; y++) {
        if (w && d && Math.abs(x - xmid) / w + Math.abs(y - ymid) / d > 1.35) continue;
        const rim = x === xmid - w || y === ymid - d;
        set(x, y, base + i,
          t > 0.83 ? edge : rim ? pink : t > 0.45 ? magenta : purple);
      }
  }
  set(cx + leanX, cy + leanY, base + height, "#ffffff");
}

// Tall crowns at the shoulders, with smaller shards radiating outward.
crystal(12, 27, 31, 14, 3, 3, -2, 0);
crystal(36, 27, 31, 14, 3, 3, 2, 0);
crystal(10, 30, 29, 11, 3, 3, -4, 2);
crystal(38, 30, 29, 11, 3, 3, 4, 2);
crystal(15, 32, 31, 12, 2, 3, -1, 3);
crystal(33, 32, 31, 12, 2, 3, 1, 3);
crystal(20, 33, 33, 12, 3, 3, -1, 3);
crystal(28, 33, 33, 12, 3, 3, 1, 3);
crystal(24, 34, 32, 14, 3, 3, 0, 3);

animate("crystal clusters", {
  type: "colors",
  palette: ["#9134cc", "#d344d7", "#fa83e6", "#ffffff"],
  pattern: "pulse",
  glow: 0.7
});