← NaturalezaObjeto 3Dfogon/rocas-planas
Lajas
Arrastrá para girarlo// «Lajas» · gpt-6-sol (medium)
// A cluster of flat stepping stones: 4-5 flat oval grey slabs of different sizes lying on the ground, slightly overlapping, with little tufts of grass between them.
// Five broad, low stepping stones, with gently irregular edges.
const stones = [
{ x: 10, y: 20, rx: 7.5, ry: 6.5, h: 2 },
{ x: 19, y: 29, rx: 8.5, ry: 6.5, h: 3 },
{ x: 31, y: 19, rx: 9.0, ry: 7.0, h: 3 },
{ x: 38, y: 30, rx: 7.0, ry: 6.0, h: 2 },
{ x: 23, y: 39, rx: 8.0, ry: 5.0, h: 2 }
];
const topHeights = new Map();
const key = (x, y) => `${x},${y}`;
for (const s of stones) {
for (let y = Math.floor(s.y - s.ry - 1); y <= Math.ceil(s.y + s.ry + 1); y++) {
for (let x = Math.floor(s.x - s.rx - 1); x <= Math.ceil(s.x + s.rx + 1); x++) {
const dx = (x - s.x) / s.rx;
const dy = (y - s.y) / s.ry;
const d = Math.sqrt(dx * dx + dy * dy);
const edge = (rand() - 0.5) * 0.065;
if (d > 1 + edge) continue;
// A narrow bevel makes the slabs chunky without making them domes.
const height = d > 0.91 + edge ? Math.max(0, s.h - 2)
: d > 0.82 + edge ? s.h - 1 : s.h;
for (let z = 0; z <= height; z++) {
const color = z === 0 ? "#777d7a" : z < height ? "#929994" : "#b7beba";
set(x, y, z, color);
}
topHeights.set(key(x, y), Math.max(height, topHeights.get(key(x, y)) ?? -1));
}
}
}
// Speckled, sunlit upper faces and occasional soft green moss.
for (const [position, z] of topHeights) {
const [x, y] = position.split(",").map(Number);
if (get(x, y, z + 1)) continue;
const n = rand();
let color = z === 0 ? "#858d87" : "#b9c1bb";
if (n < 0.08) color = "#d4d9ce";
else if (n < 0.17) color = "#a7b1aa";
else if (n < 0.205) color = "#96ad82";
else if (n < 0.225) color = "#b4c793";
set(x, y, z, color);
}
// Small cracks that read from above without breaking the rounded silhouette.
for (const [x, y, z] of [
[29, 18, 3], [30, 18, 3], [31, 17, 3],
[18, 29, 3], [19, 29, 3], [20, 30, 3],
[23, 39, 2], [24, 39, 2]
]) {
if (get(x, y, z) && !get(x, y, z + 1)) set(x, y, z, "#939e98");
}
// Bright little grass tufts tucked into the gaps between slabs.
const tufts = [
[6, 29], [11, 31], [19, 16], [22, 19],
[29, 34], [33, 37], [43, 20], [40, 39],
[13, 39], [5, 15]
];
const greens = ["#56ad48", "#72c857", "#92d969", "#429e46"];
for (const [x, y] of tufts) {
box(x, y, 0, x + 1, y + 1, 0, "#60b750");
set(x, y, 1, greens[0]);
set(x, y, 2, greens[1]);
set(x - 1, y, 1, greens[1]);
set(x - 1, y, 2, greens[2]);
set(x + 1, y + 1, 1, greens[0]);
set(x + 1, y + 1, 2, greens[2]);
set(x + 1, y, 1, greens[3]);
if (rand() > 0.35) set(x, y, 3, "#a6e477");
}import { draw } from "./assets/voxel";
import { rocasPlanas } from "./assets/rocas-planas";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, rocasPlanas, 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 rocas-planas
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["rocas-planas"] })
# Queda en client/assets/rocas-planas.ts
# https://fogon.page/object/rocas-planas