← Piezas de nivel 2Objeto 3Dfogon/nivel-cano
Caño
Arrastrá para girarlo// «Caño» · gpt-6-sol (medium)
// A green warp pipe: a vertical cylinder of radius 14, 26 tall, bright green in 3 shades with a lighter vertical highlight stripe, topped by a wider rim (radius 17, 6 tall) with a dark hollow opening on top; flat bottom on the floor.
const cx = 24, cy = 24;
const bodyR = 14, rimR = 17, openingR = 11.5;
function surfaceShade(x, y, z, rim = false) {
let color;
if (x > 31) color = rim ? "#159a36" : "#148d32";
else if (x < 20 || y < 19) color = rim ? "#43df5a" : "#35cc4b";
else color = rim ? "#28bd43" : "#23ad3d";
if (!rim && x >= 17 && x <= 19 && y < cy && z >= 3) {
color = "#78f285"; // clean vertical highlight
}
if (rim && x >= 16 && x <= 19 && y < cy && z < 31) {
color = "#69eb73";
}
return color;
}
// Flat-bottomed pipe shaft.
for (let z = 0; z <= 25; z++) {
for (let x = 10; x <= 38; x++) {
for (let y = 10; y <= 38; y++) {
const d = Math.hypot(x - cx, y - cy);
if (d > bodyR) continue;
// Recess the opening deep into the shaft.
if (z >= 19 && d < openingR) continue;
let color = surfaceShade(x, y, z);
if (z <= 1) color = x > 31 ? "#11752b" : "#198e32";
if (z === 25 && d >= 12.5) color = "#188e33";
if (z === 18 && d < openingR) color = "#103b25";
set(x, y, z, color);
}
}
}
// Chunky overhanging lip, with an actual open center.
for (let z = 26; z <= 31; z++) {
for (let x = 7; x <= 41; x++) {
for (let y = 7; y <= 41; y++) {
const d = Math.hypot(x - cx, y - cy);
if (d > rimR || d < openingR) continue;
let color = surfaceShade(x, y, z, true);
if (z === 26) color = "#138d32"; // shadow under the lip
if (z === 27 && d > 15.5) color = "#1daa3a";
if (z === 31) {
color = x > 32 ? "#35c94c" : "#70eb70"; // bright, broad top edge
if (d < 13) color = "#47d65b";
}
// Dark inner wall makes the top read as a deep hollow opening.
if (d < 12.7 && z < 31) {
color = y > cy ? "#176d32" : "#10552a";
if (z >= 29 && y > cy) color = "#208b3a";
}
set(x, y, z, color);
}
}
}import { draw } from "./assets/voxel";
import { nivelCano } from "./assets/nivel-cano";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, nivelCano, 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-cano
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["nivel-cano"] })
# Queda en client/assets/nivel-cano.ts
# https://fogon.page/object/nivel-cano