fogón

← Level pieces 23D assetfogon/nivel-lava-agrietada

Roca con lava

by fogonCC018432 blocks
Roca con lavaDrag to turn it
// «Roca con lava» · gpt-6-sol (medium)
// A square ground tile that tiles seamlessly: a full 48x48 footprint (x 0..47, y 0..47), 8 blocks thick (z 0..7), a perfectly flat solid slab with straight vertical sides and no gaps. Dark volcanic basalt rock top in 3 shades of charcoal grey crossed by a network of 1-2 block wide glowing cracks of bright orange and yellow lava running across the surface; the sides are black rock with a few thin orange glowing veins. The lava cracks glow.

const paths = [
  [[0,10],[7,10],[13,14],[20,14],[26,19],[34,17],[41,13],[48,10]],
  [[0,32],[8,29],[16,32],[22,31],[29,35],[38,30],[43,33],[48,32]],
  [[13,0],[12,8],[13,14],[17,23],[16,32],[19,40],[13,48]],
  [[37,0],[35,8],[34,17],[38,24],[38,30],[35,40],[37,48]],
  [[26,19],[25,25],[22,31]],
  [[7,10],[5,18],[8,29]],
  [[41,13],[45,22],[43,33]]
];

// Repeat the crack paths across tile boundaries so opposite edges match.
function crackDistance(x, y) {
  let best = Infinity;
  for (const path of paths) {
    for (let i = 1; i < path.length; i++) {
      for (let ox = -48; ox <= 48; ox += 48) {
        for (let oy = -48; oy <= 48; oy += 48) {
          const ax = path[i-1][0] + ox, ay = path[i-1][1] + oy;
          const bx = path[i][0] + ox, by = path[i][1] + oy;
          const dx = bx - ax, dy = by - ay;
          const t = Math.max(0, Math.min(1,
            ((x - ax) * dx + (y - ay) * dy) / (dx*dx + dy*dy)));
          best = Math.min(best, Math.hypot(x - ax - t*dx, y - ay - t*dy));
        }
      }
    }
  }
  return best;
}

const distances = [];
for (let x = 0; x < 48; x++) {
  distances[x] = [];
  for (let y = 0; y < 48; y++) {
    const d = crackDistance(x, y);
    distances[x][y] = d;

    // Every column is filled: a flat, solid, eight-block-thick tile.
    for (let z = 0; z < 7; z++) {
      let color = z < 2 ? "#171a1e" : "#202329";
      if (x === 0 || x === 47 || y === 0 || y === 47)
        color = z < 2 ? "#121417" : "#1b1e22";
      if (rand() < 0.035) color = "#262a2e";
      set(x, y, z, color);
    }

    let top = rand() < 0.18 ? "#41454a" : "#35393e";
    if (rand() < 0.09) top = "#2e3237";
    if (d < 2.1) top = "#292c30"; // dark lip around each glowing fissure
    set(x, y, 7, top);
  }
}

part("lava", [24, 24, 7]);
const orange = "#ff5a00", amber = "#ff9a1f", yellow = "#ffd23f";

for (let x = 0; x < 48; x++) {
  for (let y = 0; y < 48; y++) {
    const d = distances[x][y];
    if (d < 0.82) {
      set(x, y, 7, d < 0.36 ? yellow : (rand() < 0.6 ? amber : orange));
    }
  }
}

// Narrow veins descend from matching crack openings on all four sides.
for (let z = 3; z <= 6; z++) {
  const drift = z <= 4 ? 1 : 0;
  for (const seam of [10, 32]) {
    const v = seam + drift;
    for (const x of [0, 47])
      set(x, v, z, z === 6 ? amber : orange);
  }
  for (const seam of [13, 37]) {
    const v = seam + drift;
    for (const y of [0, 47])
      set(v, y, z, z === 6 ? yellow : orange);
  }
}

animate("lava", {
  type: "colors",
  palette: ["#ff5a00", "#ff9a1f", "#ffd23f"],
  pattern: "noise",
  glow: 0.8
});