← NaturalezaObjeto 3Dfogon/duna
Duna
Arrastrá para girarlo// «Duna» · gpt-6-sol (medium)
// A sand dune: a smooth wavy hill of golden sand in 3 shades, higher on one side with a sharp crest, with a few dry grass tufts.
const sandShadow = "#ce9947";
const sandMid = "#e7b75c";
const sandSun = "#f7d37c";
function duneHeight(x, y) {
const nx = (x - 24) / 21;
if (Math.abs(nx) >= 1) return -1;
const centerY = 24 + 1.2 * Math.sin(x * 0.19);
const radiusY = 19.5 * Math.sqrt(1 - nx * nx);
const dy = (y - centerY) / radiusY;
if (Math.abs(dy) >= 1) return -1;
// A long, gentle windward slope rises to a narrow, wandering crest.
const crest = 32 + 1.7 * Math.sin((y - 8) * 0.19);
const slope = x <= crest
? Math.pow(Math.max(0, (x - 3) / (crest - 3)), 1.12)
: Math.pow(Math.max(0, (44 - x) / (44 - crest)), 1.55);
const across = Math.pow(1 - dy * dy, 0.75);
const ripple = 0.45 * Math.sin(x * 0.39 + y * 0.13) * across;
return Math.max(0, Math.floor(18 * slope * across + ripple));
}
for (let x = 3; x <= 44; x++) {
for (let y = 4; y <= 44; y++) {
const height = duneHeight(x, y);
if (height < 0) continue;
for (let z = 0; z <= height; z++) {
let color = z < height - 3 ? sandShadow : sandMid;
if (z >= height - 1) color = sandSun;
if (z === height && rand() < 0.13) color = sandMid;
set(x, y, z, color);
}
}
}
// Sparse, sun-dried grass: short bent blades sprouting from the slopes.
const tufts = [
[11, 16], [17, 34], [22, 12],
[28, 39], [37, 17], [39, 30]
];
const grassDark = "#9e873d";
const grassLight = "#c9b460";
for (const [x, y] of tufts) {
const ground = duneHeight(x, y);
if (ground < 1) continue;
set(x, y, ground + 1, grassDark);
line(x, y, ground + 1, x - 1, y, ground + 4, 0, grassDark);
set(x - 2, y, ground + 4, grassLight);
line(x, y, ground + 1, x + 1, y - 1, ground + 3, 0, grassLight);
set(x + 2, y - 1, ground + 3, grassLight);
line(x, y, ground + 1, x, y + 1, ground + 3, 0, grassDark);
set(x, y + 2, ground + 3, grassLight);
}import { draw } from "./assets/voxel";
import { duna } from "./assets/duna";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, duna, 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 duna
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["duna"] })
# Queda en client/assets/duna.ts
# https://fogon.page/object/duna