← Kit de nivelesObjeto 3Dfogon/nivel-lava
Bloque de lava
Arrastrá para girarlo// «Bloque de lava» · gpt-6-sol (medium)
// A square lava tile that tiles seamlessly: a full 48x48 footprint (x 0..47, y 0..47), 8 blocks thick. The lower part (z 0..5) is dark cooled volcanic rock (near-black and dark red-brown) with glowing orange cracks running down the straight vertical sides; NO raised rim so tiles join into one lava lake. The top 2 layers (z 6..7) are molten lava, a separate part with animated glowing colors, with a few dark crust islands (2-4 blocks wide) floating in it and a couple of 1-block bubbles on top.
// Full-footprint volcanic slab: flat edges, with no raised rim.
const rock = ["#211b21", "#2b1d20", "#382021", "#482521"];
for (let z = 0; z <= 5; z++) {
for (let y = 0; y < 48; y++) {
for (let x = 0; x < 48; x++) {
const grain = Math.sin(x * 0.71 + y * 0.38) + Math.sin(y * 0.83 - z * 1.3);
const fleck = rand();
let shade = grain > 1.25 ? 2 : grain < -1.2 ? 0 : 1;
if (fleck < 0.035) shade = Math.min(3, shade + 1);
if (z >= 4 && fleck > 0.87) shade = Math.min(3, shade + 1);
set(x, y, z, rock[shade]);
}
}
}
// Thin, irregular hot cracks descend the four straight vertical faces.
for (let side = 0; side < 4; side++) {
const starts = side < 2 ? [6, 19, 34, 44] : [4, 17, 30, 41];
for (let i = 0; i < starts.length; i++) {
for (let z = 5; z >= (i % 2 === 0 ? 0 : 2); z--) {
const along = starts[i] + Math.round(
Math.sin(z * 1.25 + i * 2.1 + side * 0.4) * 1.15
);
const warm = z > 2 ? "#ff791e" : "#a93617";
const core = z > 2 ? "#ffc04a" : "#eb5a1b";
const mark = (p, color) => {
if (p < 0 || p > 47) return;
if (side === 0) set(p, 0, z, color);
if (side === 1) set(p, 47, z, color);
if (side === 2) set(0, p, z, color);
if (side === 3) set(47, p, z, color);
};
mark(along - 1, "#67291d");
mark(along + 1, "#67291d");
mark(along, z === 5 || (z + i) % 3 === 0 ? core : warm);
}
}
}
// The molten top is a distinct, stationary part whose colors shimmer.
part("lava", [24, 24, 6]);
const hot = ["#fff3a0", "#ffc23a", "#ff8a1f", "#f04a12", "#b8200c"];
for (let z = 6; z <= 7; z++) {
for (let y = 0; y < 48; y++) {
for (let x = 0; x < 48; x++) {
// Periodic waves meet cleanly where neighboring 48-block tiles join.
const wave =
Math.sin(2 * Math.PI * (x / 48 * 3 + 0.15 * Math.sin(2 * Math.PI * y / 48))) +
0.7 * Math.sin(2 * Math.PI * (y / 48 * 4 - 0.12 * Math.sin(2 * Math.PI * x / 48)));
const noise = (rand() - 0.5) * 0.28;
const v = wave + noise + (z === 7 ? 0.14 : -0.12);
const shade = v > 1.15 ? 0 : v > 0.45 ? 1 : v > -0.35 ? 2 : v > -1.05 ? 3 : 4;
set(x, y, z, hot[shade]);
}
}
}
animate("lava", {
type: "colors",
palette: hot,
pattern: "noise",
glow: 0.8
});
// Small cooled crust islands sit on the lava, outside its animated part.
part("body");
const islands = [
[10, 12, 4, 3], [34, 10, 3, 3], [23, 23, 4, 4],
[8, 35, 3, 4], [37, 36, 4, 3], [29, 41, 2, 3]
];
for (const [cx, cy, w, h] of islands) {
const x0 = cx - Math.floor(w / 2);
const y0 = cy - Math.floor(h / 2);
for (let dy = 0; dy < h; dy++) {
for (let dx = 0; dx < w; dx++) {
const edge = dx === 0 || dy === 0 || dx === w - 1 || dy === h - 1;
set(x0 + dx, y0 + dy, 7, edge ? "#542b25" : "#302328");
if (!edge && rand() > 0.55) set(x0 + dx, y0 + dy, 8, "#392629");
}
}
}
// Two single-block bubbles above the otherwise level surface.
set(16, 31, 8, "#ffe479");
set(40, 20, 8, "#fff3a0");import { draw } from "./assets/voxel";
import { nivelLava } from "./assets/nivel-lava";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, nivelLava, 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 nivel-lava
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["nivel-lava"] })
# Queda en client/assets/nivel-lava.ts
# https://fogon.page/object/nivel-lava