fogón

← Level kit3D assetfogon/nivel-lava

Bloque de lava

by fogonCC018437 blocks
Bloque de lavaDrag to turn it
// «Bloque de lava» · gpt-6-sol (medium)
// A square lava tile that tiles seamlessly: a full 48x48 footprint (x 0..47, y 0..47), 8 blocks thick. The lower part (z 0..5) is dark cooled volcanic rock (near-black and dark red-brown) with glowing orange cracks running down the straight vertical sides; NO raised rim so tiles join into one lava lake. The top 2 layers (z 6..7) are molten lava, a separate part with animated glowing colors, with a few dark crust islands (2-4 blocks wide) floating in it and a couple of 1-block bubbles on top.

// Full-footprint volcanic slab: flat edges, with no raised rim.
const rock = ["#211b21", "#2b1d20", "#382021", "#482521"];

for (let z = 0; z <= 5; z++) {
  for (let y = 0; y < 48; y++) {
    for (let x = 0; x < 48; x++) {
      const grain = Math.sin(x * 0.71 + y * 0.38) + Math.sin(y * 0.83 - z * 1.3);
      const fleck = rand();
      let shade = grain > 1.25 ? 2 : grain < -1.2 ? 0 : 1;
      if (fleck < 0.035) shade = Math.min(3, shade + 1);
      if (z >= 4 && fleck > 0.87) shade = Math.min(3, shade + 1);
      set(x, y, z, rock[shade]);
    }
  }
}

// Thin, irregular hot cracks descend the four straight vertical faces.
for (let side = 0; side < 4; side++) {
  const starts = side < 2 ? [6, 19, 34, 44] : [4, 17, 30, 41];
  for (let i = 0; i < starts.length; i++) {
    for (let z = 5; z >= (i % 2 === 0 ? 0 : 2); z--) {
      const along = starts[i] + Math.round(
        Math.sin(z * 1.25 + i * 2.1 + side * 0.4) * 1.15
      );
      const warm = z > 2 ? "#ff791e" : "#a93617";
      const core = z > 2 ? "#ffc04a" : "#eb5a1b";
      const mark = (p, color) => {
        if (p < 0 || p > 47) return;
        if (side === 0) set(p, 0, z, color);
        if (side === 1) set(p, 47, z, color);
        if (side === 2) set(0, p, z, color);
        if (side === 3) set(47, p, z, color);
      };
      mark(along - 1, "#67291d");
      mark(along + 1, "#67291d");
      mark(along, z === 5 || (z + i) % 3 === 0 ? core : warm);
    }
  }
}

// The molten top is a distinct, stationary part whose colors shimmer.
part("lava", [24, 24, 6]);
const hot = ["#fff3a0", "#ffc23a", "#ff8a1f", "#f04a12", "#b8200c"];
for (let z = 6; z <= 7; z++) {
  for (let y = 0; y < 48; y++) {
    for (let x = 0; x < 48; x++) {
      // Periodic waves meet cleanly where neighboring 48-block tiles join.
      const wave =
        Math.sin(2 * Math.PI * (x / 48 * 3 + 0.15 * Math.sin(2 * Math.PI * y / 48))) +
        0.7 * Math.sin(2 * Math.PI * (y / 48 * 4 - 0.12 * Math.sin(2 * Math.PI * x / 48)));
      const noise = (rand() - 0.5) * 0.28;
      const v = wave + noise + (z === 7 ? 0.14 : -0.12);
      const shade = v > 1.15 ? 0 : v > 0.45 ? 1 : v > -0.35 ? 2 : v > -1.05 ? 3 : 4;
      set(x, y, z, hot[shade]);
    }
  }
}
animate("lava", {
  type: "colors",
  palette: hot,
  pattern: "noise",
  glow: 0.8
});

// Small cooled crust islands sit on the lava, outside its animated part.
part("body");
const islands = [
  [10, 12, 4, 3], [34, 10, 3, 3], [23, 23, 4, 4],
  [8, 35, 3, 4], [37, 36, 4, 3], [29, 41, 2, 3]
];
for (const [cx, cy, w, h] of islands) {
  const x0 = cx - Math.floor(w / 2);
  const y0 = cy - Math.floor(h / 2);
  for (let dy = 0; dy < h; dy++) {
    for (let dx = 0; dx < w; dx++) {
      const edge = dx === 0 || dy === 0 || dx === w - 1 || dy === h - 1;
      set(x0 + dx, y0 + dy, 7, edge ? "#542b25" : "#302328");
      if (!edge && rand() > 0.55) set(x0 + dx, y0 + dy, 8, "#392629");
    }
  }
}

// Two single-block bubbles above the otherwise level surface.
set(16, 31, 8, "#ffe479");
set(40, 20, 8, "#fff3a0");