← AsiáticoObjeto 3Dfogon/faroles-rojos
Faroles rojos
Arrastrá para girarlo// «Faroles rojos» · gpt-6-sol (medium)
// Two wooden posts with a beam between them, hanging three round red paper lanterns with gold caps and tassels. The lanterns are the moving part: they sway gently.
// Stone feet and red-lacquered posts.
for (const x of [6, 41]) {
box(x - 3, 20, 0, x + 3, 28, 1, "#aaa9a0");
box(x - 2, 21, 2, x + 2, 27, 3, "#e3ded0");
box(x - 2, 22, 4, x + 2, 26, 33, "#8e211c");
box(x - 2, 22, 4, x + 2, 22, 33, "#bf3829");
box(x - 2, 22, 4, x - 2, 26, 33, "#a72c22");
for (const z of [5, 9, 29, 32]) {
box(x - 2, 21, z, x + 2, 27, z, "#d5a34c");
box(x - 1, 21, z, x + 1, 21, z, "#f4cb70");
}
box(x - 3, 21, 31, x + 3, 27, 33, "#71201c");
}
// Crossbeam, with a bright front edge.
box(5, 22, 33, 43, 26, 36, "#85231d");
box(5, 22, 34, 43, 22, 36, "#b93226");
box(5, 21, 33, 43, 21, 33, "#e0aa50");
box(5, 21, 36, 43, 21, 36, "#efc36a");
box(9, 21, 30, 11, 25, 32, "#a82c23");
box(37, 21, 30, 39, 25, 32, "#a82c23");
// A shallow glazed-tile canopy with upturned ends.
for (let x = 3; x <= 45; x++) {
for (let y = 18; y <= 30; y++) {
const rise = Math.floor((6 - Math.abs(y - 24)) / 3);
const tip = (x <= 5 || x >= 43) ? 1 : 0;
const z = 38 + rise + tip;
set(x, y, z - 1, "#263f38");
set(x, y, z, (x + y) % 4 === 0 ? "#598478" : "#39665c");
if (x % 4 === 0 && y > 18 && y < 30) set(x, y, z, "#729789");
}
}
for (const y of [18, 30]) {
for (let x = 3; x <= 45; x++) {
set(x, y, (x <= 5 || x >= 43) ? 40 : 38, "#244c49");
}
}
box(5, 23, 41, 43, 25, 41, "#638c7c");
// Each lantern, including its cord, has its own hanging pivot.
const lanterns = [
{ x: 14, speed: 1.05, amplitude: 0.22 },
{ x: 24, speed: 0.88, amplitude: 0.26 },
{ x: 34, speed: 1.16, amplitude: 0.20 }
];
for (let i = 0; i < lanterns.length; i++) {
const { x, speed, amplitude } = lanterns[i];
const name = `lantern${i + 1}`;
part(name, [x, 20, 33]);
box(x, 20, 30, x, 20, 32, "#e7b85e");
box(x - 1, 19, 29, x + 1, 21, 29, "#efcb78");
// Solid, rounded paper body, shaded toward its front and underside.
for (let dx = -4; dx <= 4; dx++) {
for (let dy = -4; dy <= 4; dy++) {
for (let dz = -5; dz <= 5; dz++) {
if ((dx * dx + dy * dy) / 16 + dz * dz / 25 > 1) continue;
let color = dy <= -2 ? "#ed5140" : "#c52c2b";
if (dz < -2) color = dy <= -2 ? "#d93a32" : "#a82427";
if (dy >= 2) color = "#a82327";
if (rand() < 0.08) color = dy < 0 ? "#f1644c" : "#b42a29";
set(x + dx, 20 + dy, 22 + dz, color);
}
}
}
// Fine gold ribs following the curved front of the paper.
for (const dx of [-2, 2]) {
for (let z = 19; z <= 25; z++) {
const q = 1 - dx * dx / 16 - (z - 22) ** 2 / 25;
if (q > 0) {
const frontY = 20 - Math.floor(4 * Math.sqrt(q));
set(x + dx, frontY - 1, z, "#d8994a");
}
}
}
cylinder(x, 20, 27, 2, 2, "#d8a547");
box(x - 1, 19, 28, x + 1, 21, 28, "#f5d079");
cylinder(x, 20, 16, 2, 2, "#d4a04b");
box(x - 1, 18, 18, x + 1, 18, 18, "#f4cf76");
// A small, legible gold emblem on the front.
set(x, 15, 22, "#f7d27c");
set(x, 16, 23, "#f7d27c");
set(x - 1, 16, 21, "#e9b75d");
set(x + 1, 16, 21, "#e9b75d");
box(x, 20, 13, x, 20, 15, "#e8b95d");
for (let t = -1; t <= 1; t++) {
box(x + t, 20, 10 + Math.abs(t), x + t, 20, 13, t === 0 ? "#efbd55" : "#a92a29");
}
animate(name, { type: "swing", axis: "x", speed, amplitude });
}
part("body");import { draw } from "./assets/voxel";
import { farolesRojos } from "./assets/faroles-rojos";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, farolesRojos, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: lo que mide en px su lado más largo
// angle: giro sobre el piso, en radianes
// t: segundos; si se mueve, se anima solo con eso# En una terminal, en la carpeta del juego
fogon assets add faroles-rojos
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["faroles-rojos"] })
# Queda en client/assets/faroles-rojos.ts
# https://fogon.page/object/faroles-rojos