fogón

← Monstruos y enemigosObjeto 3Dfogon/dragon-de-lava

Dragón de lava

de fogonCC010446 bloques
Dragón de lavaArrastrá para girarlo
// «Dragón de lava» · gpt-6-sol (medium)
// A big boss: a huge cartoon lava dragon on four legs, horizontal, head toward -y: black volcanic rock scales with glowing orange-yellow lava cracks, curved horns, burning yellow eyes, an open mouth with a lava glow, big spiked bat wings raised, and a long spiked tail.

const rock = "#25232c", rockLight = "#3b3941", rockDark = "#17151d";
const lava = "#ed571d", hot = "#ffad26", yellow = "#ffe25a";
const membrane = "#81342e", membraneLight = "#a8442d";

function wing(side) {
  const X = x => side < 0 ? x : 48 - x;
  const name = side < 0 ? "leftWing" : "rightWing";
  part(name, [X(16), 24, 27]);

  // A scalloped bat-wing silhouette, raised behind the shoulders.
  const outline = [
    [16, 26], [13, 34], [8, 41], [3, 43], [4, 37],
    [8, 35], [6, 30], [12, 32], [11, 26]
  ];
  function inside(x, z) {
    let hit = false;
    for (let i = 0, j = outline.length - 1; i < outline.length; j = i++) {
      const a = outline[i], b = outline[j];
      if ((a[1] > z) !== (b[1] > z) &&
          x < (b[0] - a[0]) * (z - a[1]) / (b[1] - a[1]) + a[0]) hit = !hit;
    }
    return hit;
  }
  for (let x = 3; x <= 16; x++)
    for (let z = 26; z <= 43; z++)
      if (inside(x + 0.5, z + 0.5)) {
        const y = Math.round(24 + (16 - x) * 0.38);
        const c = z > 36 ? membraneLight : membrane;
        set(X(x), y, z, c);
        set(X(x), y + 1, z, "#57282b");
        if (rand() < 0.09) set(X(x), y - 1, z, "#d35b28");
      }

  const rib = (x0, z0, x1, z1) => {
    const y0 = Math.round(24 + (16 - x0) * 0.38) - 1;
    const y1 = Math.round(24 + (16 - x1) * 0.38) - 1;
    line(X(x0), y0, z0, X(x1), y1, z1, 1, rockDark);
    line(X(x0), y0 - 1, z0, X(x1), y1 - 1, z1, 0, "#df6428");
  };
  rib(16, 27, 3, 43);
  rib(16, 27, 8, 35);
  rib(16, 27, 6, 30);
  line(X(16), 24, 27, X(13), 25, 34, 1, rockLight);
  animate(name, { type: "swing", axis: "y", speed: side < 0 ? 3 : -3, amplitude: 0.35 });
}
wing(-1);
wing(1);

function leg(name, x, y, speed) {
  part(name, [x, y, 16]);
  ellipsoid(x, y, 10, 3.5, 3.5, 7, rockDark);
  ellipsoid(x, y - 1, 10, 3, 3, 6, rock);
  ellipsoid(x, y - 2, 2, 3.5, 4, 2, rockLight);
  box(x - 3, y - 5, 0, x + 3, y + 1, 1, rockDark);
  for (let dx of [-2, 0, 2]) {
    box(x + dx, y - 6, 0, x + dx, y - 4, 2, rockLight);
    set(x + dx, y - 7, 0, "#ec9a3d");
  }
  // Chunky orange seams at the knee.
  line(x - 2, y - 3, 9, x, y - 3, 7, 0, lava);
  line(x, y - 3, 7, x + 2, y - 2, 8, 0, hot);
  animate(name, { type: "swing", axis: "x", speed, amplitude: 0.3 });
}
leg("frontLeft", 17, 16, 3);
leg("frontRight", 31, 16, -3);
leg("rearLeft", 17, 30, -3);
leg("rearRight", 31, 30, 3);

part("body");
ellipsoid(24, 24, 19, 10, 12, 9, rockDark);
ellipsoid(24, 23, 20, 9, 11, 8, rock);
ellipsoid(24, 16, 19, 8, 6, 7, rockLight);

// Curving, tapering tail with an ember-colored underside.
for (let i = 0; i < 12; i++) {
  const y = 33 + i;
  const r = Math.max(1.3, 5 - i * 0.32);
  ellipsoid(24 + Math.round(Math.sin(i * 0.32) * 2), y, 17 + Math.round(i * 0.12),
            r, 2.5, r * 0.72, i % 3 === 0 ? rockLight : rock);
}
line(24, 39, 15, 25, 45, 17, 0, lava);
line(25, 43, 17, 25, 46, 18, 0, hot);

// Raised volcanic plates down the back and tail.
for (let y of [19, 23, 27, 31, 35, 39, 43]) {
  const tip = y < 35 ? 32 : Math.max(21, 31 - (y - 35));
  const base = y < 35 ? 27 : Math.max(19, 25 - (y - 35) * 0.5);
  for (let z = Math.ceil(base); z <= tip; z++) {
    const w = Math.max(0, Math.floor((tip - z) * 0.42));
    box(24 - w, y, z, 24 + w, y + 1, z, z === tip ? "#dc6930" : rockDark);
  }
}

// Oversized friendly-cartoon dragon head and square snout.
ellipsoid(24, 10, 22, 9, 8, 7, rockDark);
ellipsoid(24, 9, 23, 8, 7, 6, rock);
box(19, 2, 21, 29, 8, 24, rockLight);
box(20, 1, 22, 28, 4, 24, rock);
box(19, 2, 20, 29, 5, 20, rockDark);

// Deep open mouth, molten throat, and a projecting lower jaw.
box(19, 1, 16, 29, 4, 19, "#100e18");
box(21, 3, 17, 27, 4, 18, "#d83c16");
box(22, 2, 17, 26, 3, 18, hot);
box(20, 2, 13, 28, 8, 15, rockDark);
box(21, 1, 14, 27, 5, 15, rockLight);
box(21, 2, 16, 27, 3, 16, lava);
for (let x of [20, 23, 26, 28]) {
  set(x, 1, 19, "#ffdf91");
  set(x, 1, 16, "#ffdf91");
}

// Wide glowing eyes beneath heavy brows.
for (let x of [19, 29]) {
  box(x - 2, 3, 25, x + 2, 5, 28, rockDark);
  box(x - 1, 2, 25, x + 1, 3, 27, yellow);
  set(x, 1, 26, "#fff5a1");
  box(x - 2, 1, 28, x + 2, 4, 29, rockDark);
}
for (let x of [21, 27]) {
  set(x, 1, 22, rockDark);
  set(x, 1, 23, rockDark);
}

// Paired backward-curving horns.
for (let x of [17, 31]) {
  line(x, 10, 27, x, 12, 32, 2, rockDark);
  line(x, 12, 32, x + (x < 24 ? -2 : 2), 16, 35, 1, rockLight);
  line(x + (x < 24 ? -2 : 2), 16, 35,
       x + (x < 24 ? -3 : 3), 18, 36, 0, "#d47a3b");
}

// Small armor scales on the shoulders and upper back.
for (let y = 16; y <= 32; y += 3)
  for (let x = 17; x <= 31; x += 3) {
    const q = 1 - ((x - 24) / 10) ** 2 - ((y - 24) / 12) ** 2;
    if (q > 0.16 && rand() < 0.8) {
      const z = Math.round(19 + 9 * Math.sqrt(q));
      set(x, y, z, rand() < 0.35 ? "#50434a" : rockLight);
    }
  }

// Surface-following lava fissures belong to one glowing color-cycling part.
part("lavaCracks");
const crackColors = ["#aa261d", lava, hot, yellow];
function frontPoint(cx, cy, cz, rx, ry, rz, x, z, color) {
  const q = 1 - ((x - cx) / rx) ** 2 - ((z - cz) / rz) ** 2;
  if (q > 0.04) {
    const y = Math.round(cy - ry * Math.sqrt(q)) - 1;
    set(x, y, z, color);
    if (rand() < 0.22) set(x, y - 1, z, hot);
  }
}
for (let x = 17; x <= 31; x++) {
  const z = 20 + Math.round(2 * Math.sin(x * 0.8));
  frontPoint(24, 23, 20, 9, 11, 8, x, z, crackColors[x % 4]);
  if (x % 4 === 0) {
    frontPoint(24, 23, 20, 9, 11, 8, x, z + 1, lava);
    frontPoint(24, 23, 20, 9, 11, 8, x + 1, z - 1, hot);
  }
}
for (let x = 19; x <= 29; x++) {
  const z = 18 + Math.round(Math.sin(x * 0.9));
  frontPoint(24, 10, 22, 9, 8, 7, x, z, x % 3 ? lava : hot);
}
for (let y = 18; y <= 31; y += 4)
  for (let dx of [-7, 7]) {
    const x = 24 + dx;
    const z = 22 + Math.round(Math.sin(y) * 2);
    frontPoint(24, 23, 20, 9, 11, 8, x, z, hot);
  }
animate("lavaCracks", {
  type: "colors",
  palette: ["#92231b", "#e94c19", "#ffad26", "#ffe45d"],
  pattern: "noise",
  glow: 0.8
});