fogón

← Piezas de nivel 2Objeto 3Dfogon/nivel-bolsa-de-monedas

Bolsa de monedas

de fogonCC022790 bloques
Bolsa de monedasArrastrá para girarlo
// «Bolsa de monedas» · gpt-6-sol (medium)
// A fat brown burlap money sack tied at the top with a golden rope, a big gold coin symbol painted on the front (-y), with a few gold coins spilling out of the opening and three coins lying on the floor in front of it.

// A plump burlap sack, centered behind three spilled coins.
const cx = 24, cy = 27;
const cloth = ["#9b5c2e", "#ad6b34", "#bb7940", "#c8894b", "#d49656"];
const gold = "#ffcb35", goldLight = "#ffe375", goldDark = "#d98a18";

// Shape the sack layer by layer: broad belly, gathered shoulders, narrow neck.
const profile = [
  [0, 8, 7], [3, 12, 11], [8, 16, 14], [15, 17, 16],
  [21, 17, 16], [26, 15, 14], [30, 11, 10],
  [32, 8, 8], [35, 7, 7]
];
function radii(z) {
  for (let i = 1; i < profile.length; i++) {
    if (z <= profile[i][0]) {
      const a = profile[i - 1], b = profile[i];
      const t = (z - a[0]) / (b[0] - a[0]);
      return [a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
    }
  }
  return [7, 7];
}
function frontY(x, z) {
  for (let y = 8; y <= 43; y++) if (get(x, y, z)) return y;
  return null;
}

for (let z = 0; z <= 35; z++) {
  const [rx, ry] = radii(z);
  for (let x = 6; x <= 42; x++) {
    for (let y = 10; y <= 43; y++) {
      const d = ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2;
      if (d > 1) continue;
      let shade = z < 7 ? 0 : z < 16 ? 1 : z < 27 ? 2 : 3;
      if (y < cy - 5) shade++;
      if (x > cx + 10) shade--;
      if (rand() < 0.035) shade += rand() < 0.5 ? -1 : 1;
      set(x, y, z, cloth[Math.max(0, Math.min(4, shade))]);
    }
  }
}

// A few subtle folds and individual stitches on the visible burlap.
for (const x of [12, 16, 33, 37]) {
  for (let z = 7; z <= 25; z++) {
    const y = frontY(x, z);
    if (y !== null && (z + x) % 5 !== 0)
      set(x, y - 1, z, z % 4 === 0 ? "#d99a59" : "#9e602f");
  }
}
for (let x = 12; x <= 36; x += 3) {
  const y = frontY(x, 6);
  if (y !== null) set(x, y - 1, 6, "#db9d5c");
}

// Large, curved gold coin emblem painted across the front.
for (let z = 8; z <= 28; z++) {
  for (let x = 14; x <= 34; x++) {
    const d = Math.sqrt(((x - 24) / 10.5) ** 2 + ((z - 18) / 10.5) ** 2);
    if (d > 1) continue;
    const y = frontY(x, z);
    if (y === null) continue;
    const rim = d > 0.82;
    set(x, y - 1, z, rim ? goldDark : (z > 19 ? goldLight : gold));
    if (rim && z > 19 && x < 29) set(x, y - 2, z, "#ffdf69");
  }
}

// An embossed dollar mark, including its two short vertical strokes.
const mark = [
  "...###...",
  "..#...#..",
  "..#......",
  "...###...",
  "......#..",
  "......#..",
  "..#...#..",
  "...###..."
];
for (let row = 0; row < mark.length; row++) {
  const z = 23 - row;
  for (let col = 0; col < 9; col++) {
    if (mark[row][col] !== "#") continue;
    const x = 20 + col, y = frontY(x, z);
    if (y !== null) set(x, y - 2, z, "#ae6912");
  }
}
for (let z = 13; z <= 25; z++) {
  const y = frontY(24, z);
  if (y !== null) set(24, y - 2, z, "#ae6912");
}

// Gathered, open top: dark hollow center and a thick folded burlap lip.
for (let z = 36; z <= 38; z++) {
  for (let x = 15; x <= 33; x++) {
    for (let y = 18; y <= 36; y++) {
      const d = ((x - 24) / 9) ** 2 + ((y - 27) / 8) ** 2;
      if (d <= 1 && d >= 0.49)
        set(x, y, z, z === 38 ? "#df9b58" : "#b5753b");
      else if (d < 0.49 && z === 36)
        set(x, y, z, "#704020");
    }
  }
}
for (let x = 16; x <= 32; x++) {
  for (let y = 19; y <= 35; y++) {
    const d = ((x - 24) / 8.5) ** 2 + ((y - 27) / 7.5) ** 2;
    if (d > 0.70 && d <= 1) set(x, y, 39, "#e5a35e");
  }
}

// Chunky golden rope wrapped around the neck.
for (let a = 0; a < 360; a += 3) {
  const t = a * Math.PI / 180;
  const x = Math.round(24 + 8.1 * Math.cos(t));
  const y = Math.round(27 + 8.0 * Math.sin(t));
  set(x, y, 32, goldDark);
  set(x, y, 33, a % 18 < 9 ? goldLight : gold);
}
sphere(24, 18, 33, 2, gold);
set(23, 16, 34, "#fff0a0");
line(22, 17, 32, 19, 15, 27, 1, goldDark);
line(26, 17, 32, 29, 15, 28, 1, gold);
set(19, 15, 27, goldLight);
set(29, 15, 28, goldLight);

// Coins visible at the mouth, with a couple leaning out toward the viewer.
function uprightCoin(x, y, z, r) {
  for (let dx = -r; dx <= r; dx++) {
    for (let dz = -r; dz <= r; dz++) {
      const d = dx * dx + dz * dz;
      if (d > r * r) continue;
      for (let yy = y; yy <= y + 2; yy++)
        set(x + dx, yy, z + dz,
          d > (r - 0.8) ** 2 ? goldDark : (dz > 0 ? goldLight : gold));
    }
  }
  set(x, y - 1, z, "#fff0a0");
}
uprightCoin(20, 23, 38, 3);
uprightCoin(27, 25, 39, 3);
uprightCoin(29, 19, 36, 2);
uprightCoin(18, 20, 36, 2);

// Three separate, thick coins lying flat on the floor in front.
function floorCoin(x, y, r) {
  for (let dx = -r; dx <= r; dx++) {
    for (let dy = -r; dy <= r; dy++) {
      const d = dx * dx + dy * dy;
      if (d > r * r) continue;
      set(x + dx, y + dy, 0, goldDark);
      set(x + dx, y + dy, 1,
        d > (r - 0.9) ** 2 ? "#e99c1f" : gold);
      if (d <= (r - 0.9) ** 2)
        set(x + dx, y + dy, 2, dy < 0 ? goldLight : gold);
    }
  }
  set(x, y, 3, "#fff0a0");
  set(x + 1, y, 3, goldDark);
}
floorCoin(14, 5, 3);
floorCoin(24, 6, 4);
floorCoin(35, 5, 3);