fogón

← Level kit3D assetfogon/nivel-puerta

Puerta

by fogonCC015268 blocks
PuertaDrag to turn it
// «Puerta» · gpt-6-sol (medium)
// A modular wall segment with a door, matching the brick wall: exactly 48 blocks long on x (x 0..47), 10 thick on y (y 19..28), 40 tall, red bricks in running bond with light grey mortar and a light grey stone cap on top. In the middle, an arched opening 18 wide and 28 tall with a light stone arch frame. Inside it, a wooden door leaf (brown vertical planks in 2 shades, two dark iron bands, a round gold knob on the right) 2 blocks thick, set at the front of the opening. The door leaf is a separate part hinged on its left edge.

const brick = ["#c95740", "#dc694b", "#e77755"];
const mortar = "#deddd4";
const stone = ["#c5c9c8", "#d9dcda", "#edf0eb"];

function opening(x, z) {
  if (z < 0 || z > 27 || x < 15 || x > 32) return false;
  if (z <= 18) return true;
  const t = (z - 18) / 10;
  return Math.abs(x - 23.5) <= 9 * Math.sqrt(1 - t * t);
}

function nearOpening(x, z) {
  for (let dz = -2; dz <= 2; dz++) {
    for (let dx = -2; dx <= 2; dx++) {
      if (opening(x + dx, z + dz)) return true;
    }
  }
  return false;
}

// Running-bond brickwork, with mortar joints continuing through the wall.
for (let z = 0; z <= 36; z++) {
  const course = Math.floor(z / 4);
  const shift = course % 2 ? 4 : 0;
  for (let x = 0; x < 48; x++) {
    if (opening(x, z)) continue;

    const frame = nearOpening(x, z);
    let color;
    if (frame) {
      // Large, clean stone voussoirs around the arch.
      const joint = z <= 18
        ? (z % 5 === 0)
        : ((x + 48) % 5 === 0 && z >= 21);
      color = joint ? stone[0] : stone[z % 6 === 0 ? 2 : 1];
    } else if (z % 4 === 0 || (x + shift) % 8 === 0) {
      color = mortar;
    } else {
      color = brick[(Math.floor((x + shift) / 8) + course * 2) % 3];
      if (z % 4 === 3) color = brick[2];
    }

    for (let y = 19; y <= 28; y++) set(x, y, z, color);
  }
}

// Continuous light-stone cap, kept inside the modular footprint.
box(0, 19, 37, 47, 28, 37, stone[0]);
box(0, 19, 38, 47, 28, 38, stone[1]);
box(0, 19, 39, 47, 28, 39, stone[2]);

// The leaf is attached at its left edge, independently of the masonry.
part("puerta", [15, 20, 0]);

function inDoor(x, z) {
  if (x < 16 || x > 31 || z < 0 || z > 25) return false;
  if (z <= 17) return true;
  const t = (z - 17) / 9;
  return Math.abs(x - 23.5) <= 8 * Math.sqrt(1 - t * t);
}

for (let z = 0; z <= 25; z++) {
  for (let x = 16; x <= 31; x++) {
    if (!inDoor(x, z)) continue;
    const plank = Math.floor((x - 16) / 3);
    const wood = plank % 2 ? "#a95e32" : "#c5773b";
    set(x, 20, z, "#824828");
    set(x, 19, z, (x - 16) % 3 === 2 ? "#874923" : wood);
  }
}

// Chunky iron straps and hinge plates on the visible face.
for (const z of [6, 7, 17, 18]) {
  for (let x = 16; x <= 31; x++) {
    if (inDoor(x, z)) set(x, 19, z, z === 7 || z === 18 ? "#485158" : "#303940");
  }
}
for (const z of [4, 5, 14, 15]) {
  box(16, 19, z, 17, 19, z, "#41494e");
  set(17, 19, z, "#87908c");
}

// Round gold knob on the right, with a bright highlight.
for (let z = 10; z <= 12; z++) {
  for (let x = 28; x <= 30; x++) {
    if (Math.abs(x - 29) + Math.abs(z - 11) <= 2) {
      set(x, 19, z, "#d99520");
    }
  }
}
set(29, 19, 11, "#ffe277");
set(28, 19, 12, "#fff0a1");

animate("puerta", { type: "swing", axis: "z", speed: 0.7, amplitude: 0.9 });