fogón

← BásicoObjeto 3Dfogon/puentecito

Puentecito

de fogonCC010487 bloques
PuentecitoArrastrá para girarlo
// «Puentecito» · gpt-6-sol (medium)
// Footbridge («Puentecito»).

const C = {
  dirt: ["#60432f", "#704e35", "#80593b"],
  grass: ["#648d43", "#76a04b", "#85ad53", "#94b75e"],
  water: ["#2499a8", "#2baabb", "#39b8c6"],
  woodDark: "#77502e",
  woodSide: "#996638",
  wood: ["#af7941", "#bd884b", "#ca9554"],
  woodTop: ["#d5a362", "#e3b371", "#e9be7d"],
  woodLight: "#efc484"
};

// Low, slightly irregular square of earth.
for (let x = 4; x <= 43; x++) {
  for (let y = 4; y <= 43; y++) {
    if ((x < 7 || x > 40) && (y < 7 || y > 40)) continue;
    for (let z = 0; z <= 3; z++)
      set(x, y, z, C.dirt[Math.min(2, Math.floor(rand() * 3))]);
    set(x, y, 4, C.grass[Math.floor(rand() * C.grass.length)]);
  }
}

// A stream crosses beneath the bridge. Its uneven grassy banks remain visible.
for (let x = 5; x <= 42; x++) {
  const near = 14 + Math.round(1.3 * Math.sin(x * 0.48));
  const far = 32 + Math.round(1.2 * Math.sin(x * 0.39 + 1));
  for (let y = near; y <= far; y++) {
    set(x, y, 4, C.water[Math.floor(rand() * C.water.length)]);
    if (rand() < 0.12)
      set(x, y, 4, "#46c3ce");
  }
  for (const y of [near - 1, far + 1]) {
    if (y >= 5 && y <= 42)
      set(x, y, 4, C.grass[Math.floor(rand() * C.grass.length)]);
  }
}

// Bright, broken reflections between the bridge and the shore.
for (const [x, y, len] of [
  [34, 19, 3], [38, 23, 2], [35, 27, 4],
  [10, 23, 2], [31, 30, 2], [40, 17, 2]
]) {
  for (let i = 0; i < len; i++) set(x + i, y, 5, "#a1e6da");
}

// Tufts of grass along the water's edge.
for (let i = 0; i < 105; i++) {
  const x = 6 + Math.floor(rand() * 36);
  const y = rand() < 0.5
    ? 9 + Math.floor(rand() * 6)
    : 33 + Math.floor(rand() * 7);
  if (get(x, y, 4) && get(x, y, 4)[1] !== "2") {
    set(x, y, 5, rand() < 0.5 ? "#82ac50" : "#99ba60");
    if (rand() < 0.18) set(x, y, 6, "#9abc62");
  }
}

// A few pale river stones.
for (const [x, y] of [[36, 34], [39, 35], [9, 34], [11, 32], [38, 12]]) {
  box(x, y, 5, x + 1, y + 1, 5, "#838d79");
  set(x, y, 6, "#b5b7a0");
  set(x + 1, y, 6, "#a4aa91");
}

// The bridge runs from the near bank to the far bank.
function deckHeight(y) {
  if (y <= 19) return 6 + Math.floor((y - 6) * 7 / 13);
  if (y <= 27) return 13;
  return 13 - Math.floor((y - 27) * 7 / 14);
}

// Heavy beams following the rise and fall of the deck.
for (let y = 6; y <= 41; y++) {
  const h = deckHeight(y);
  for (const x of [15, 16, 29, 30]) {
    box(x, y, h - 3, x, y, h - 1,
      x === 15 || x === 30 ? C.woodDark : C.woodSide);
  }

  // Solid crosswise planks, individually readable as little steps.
  for (let x = 16; x <= 29; x++) {
    set(x, y, h - 1, C.wood[Math.floor(rand() * C.wood.length)]);
    set(x, y, h,
      rand() < 0.16 ? C.woodTop[0] : C.woodTop[(y + x) % 3]);
  }
  set(16, y, h, "#f0c17e");
  set(29, y, h, "#b37d42");

  // Dark seams emphasize the separate boards.
  if (y % 3 === 0)
    for (let x = 18; x <= 27; x++)
      set(x, y, h, "#b48148");
}

// Stout feet planted on either bank, leaving the channel open below.
for (const y of [9, 12, 36, 39]) {
  for (const x of [15, 30])
    box(x, y, 5, x + 1, y + 1, deckHeight(y) - 2, C.woodDark);
}

// Rail posts on both sides, with square pale caps.
const posts = [7, 12, 17, 22, 27, 32, 37, 41];
for (const x of [14, 31]) {
  for (const y of posts) {
    const h = deckHeight(y);
    box(x, y, h - 2, x + 1, y + 1, h + 8, C.woodSide);
    box(x, y, h + 8, x + 1, y + 1, h + 9, C.woodTop[1]);
    box(x, y, h + 10, x + 1, y + 1, h + 10, C.woodLight);
    set(x + 1, y + 1, h + 8, C.woodDark);
  }

  // Continuous handrails and a lower rail follow the arched walkway.
  for (let y = 7; y < 41; y++) {
    const h = deckHeight(y);
    box(x, y, h + 7, x + 1, y + 1, h + 8, C.woodTop[0]);
    set(x, y, h + 9, C.woodLight);
    box(x, y, h + 3, x, y + 1, h + 4, C.woodSide);
    set(x, y, h + 4, "#cb9655");
  }

  // Slim upright balusters between the main posts.
  for (let y = 9; y <= 39; y += 2) {
    if (posts.some(p => Math.abs(p - y) <= 1)) continue;
    const h = deckHeight(y);
    box(x, y, h + 1, x, y, h + 7, "#a8733c");
    set(x, y, h + 5, "#d09c5d");
  }
}

// Chunky end steps, complete with light-colored nosings.
for (const y of [6, 7, 8, 9, 10, 11, 38, 39, 40, 41]) {
  const h = deckHeight(y);
  for (let x = 17; x <= 28; x++)
    if (x % 4 !== 0) set(x, y, h, "#dfad6c");
  box(17, y, h, 28, y, h, "#d8a362");
  for (const x of [17, 21, 25, 28]) set(x, y, h, "#ebba78");
}

// Small sprigs on the grassy bank.
for (const [x, y] of [[7, 12], [11, 38], [35, 37], [40, 35], [39, 11]]) {
  line(x, y, 5, x, y, 7, 0, "#547b3c");
  set(x - 1, y, 6, "#82a74a");
  set(x + 1, y, 6, "#8daf54");
}