← FantasíaObjeto 3Dfogon/puente-de-cristal
Puente de cristal
Arrastrá para girarlo// «Puente de cristal» · gpt-6-sol (medium)
// An arched bridge made of translucent-looking crystal blocks in light cyan and pale violet, with crystal railings and glowing spikes at each end post, spanning left to right (along x) over a small patch of dark rock at each end.
const C = {
rock: "#303643", rockLight: "#49515d", rockDark: "#252b38",
moss: "#668472", mossLight: "#83a98c",
cyan: "#8cebf0", cyanLight: "#d9ffff", cyanDeep: "#43b9ce",
violet: "#bba8f0", violetLight: "#e6d9ff", violetDeep: "#8375bb",
glow: "#f6ffff"
};
function deckZ(x) {
const t = (x - 24) / 16;
return Math.round(7 + 8 * (1 - t * t));
}
// Little rocky banks at either end of the crossing.
for (const cx of [8, 40]) {
for (let x = cx - 5; x <= cx + 5; x++) {
for (let y = 15; y <= 33; y++) {
const d = ((x - cx) / 5.4) ** 2 + ((y - 24) / 9.5) ** 2;
if (d > 1.12 || rand() < 0.045) continue;
const h = Math.max(0, Math.floor(3.4 - d * 2.5 + rand() * 1.4));
for (let z = 0; z <= h; z++)
set(x, y, z, rand() < 0.22 ? C.rockLight : C.rock);
if (rand() < 0.38) set(x, y, h + 1, rand() < 0.5 ? C.moss : C.mossLight);
}
}
box(cx - 2, 20, 1, cx + 2, 28, 5, C.rockDark);
box(cx - 2, 20, 5, cx + 2, 28, 5, C.rockLight);
}
// Solid, gently cambered crystal walkway.
for (let x = 8; x <= 40; x++) {
const z = deckZ(x);
for (let y = 20; y <= 28; y++) {
for (let k = 2; k >= 0; k--) {
let color = k === 0 ? C.cyanLight : k === 1 ? C.cyan : C.cyanDeep;
if (y === 20 || y === 28) color = k === 0 ? C.violetLight : C.violet;
if (k === 0 && (x + y) % 7 === 0) color = C.violetLight;
set(x, y, z - k, color);
}
if (y > 20 && y < 28 && x % 4 === 0)
set(x, y, z, (x + y) % 3 === 0 ? C.glow : C.cyan);
}
// Two exposed, sparkling arch ribs; the open space beneath stays clear.
for (const y of [19, 29]) {
box(x, y, z - 4, x, y, z - 2, C.violetDeep);
set(x, y, z - 4, x % 4 === 0 ? C.violetLight : C.cyanDeep);
set(x, y, z - 3, C.violet);
set(x, y, z - 2, C.cyan);
}
// Low, continuous rails with alternating crystal facets.
for (const y of [18, 30]) {
set(x, y, z + 1, C.violetDeep);
set(x, y, z + 2, x % 3 === 0 ? C.violetLight : C.cyan);
set(x, y, z + 3, x % 4 === 0 ? C.glow : C.violet);
}
}
// Small pendant crystals under the arch.
for (const x of [13, 19, 24, 29, 35]) {
for (const y of [19, 29]) {
const z = deckZ(x) - 5;
set(x, y, z, C.cyan);
set(x, y, z - 1, C.cyanLight);
if (x === 24) set(x, y, z - 2, C.glow);
}
}
// A few friendly luminous mushrooms growing from the stone.
for (const [x, y, z] of [[5, 18, 2], [11, 32, 2], [37, 16, 2], [43, 30, 2]]) {
set(x, y, z, "#d9cadd");
box(x - 1, y, z + 1, x + 1, y, z + 1, "#eaa0df");
set(x, y, z + 2, "#ffd7f3");
}
// Only the crystal posts pulse; their darker mounting sockets stay still.
for (const x of [8, 16, 24, 32, 40]) {
for (const y of [18, 30]) {
const z = deckZ(x);
box(x - 1, y, z + 1, x + 1, y, z + 1, C.violetDeep);
set(x, y, z + 2, C.violet);
}
}
part("crystal_posts", [24, 24, 12]);
for (const x of [8, 16, 24, 32, 40]) {
for (const y of [18, 30]) {
const z = deckZ(x);
const end = x === 8 || x === 40;
const height = end ? 7 : 5;
for (let dz = 3; dz <= height - 2; dz++) {
box(x - 1, y, z + dz, x + 1, y, z + dz,
dz % 2 ? C.cyan : C.violet);
set(x, y - 1, z + dz, dz % 2 ? C.cyanLight : C.violetLight);
}
box(x - 1, y, z + height - 1, x + 1, y, z + height - 1, C.cyanLight);
set(x, y, z + height, C.glow);
if (end) set(x, y, z + height + 1, C.violetLight);
}
}
animate("crystal_posts", {
type: "colors",
palette: ["#65e7f2", "#f6ffff", "#c5a8ff"],
pattern: "pulse",
glow: 0.6
});import { draw } from "./assets/voxel";
import { puenteDeCristal } from "./assets/puente-de-cristal";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, puenteDeCristal, 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 puente-de-cristal
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["puente-de-cristal"] })
# Queda en client/assets/puente-de-cristal.ts
# https://fogon.page/object/puente-de-cristal