← BásicoObjeto 3Dfogon/colador
Colador
Arrastrá para girarlo// «Colador» · gpt-6-sol (medium)
// Colander («Colador»).
// Brushed-metal colander with a perforated, rounded bowl.
const metal = ["#647780", "#788b93", "#91a2a8", "#aebbbd", "#c7d0cf"];
function steel(x, y, z, bright = 0) {
let shade = 2 + bright + (z > 23 ? 0.4 : 0) + (y < 24 ? -0.35 : 0);
shade += (rand() - 0.5) * 1.5;
return metal[Math.max(0, Math.min(4, Math.round(shade)))];
}
function radius(z) {
const stops = [
[5, 6], [8, 9], [12, 12], [16, 14.5],
[20, 16.5], [25, 18], [29, 18.8], [31, 19]
];
for (let i = 1; i < stops.length; i++) {
if (z <= stops[i][0]) {
const [za, ra] = stops[i - 1];
const [zb, rb] = stops[i];
return ra + (rb - ra) * (z - za) / (zb - za);
}
}
return 19;
}
// A shallow square pedestal beneath the bowl.
box(19, 19, 2, 29, 29, 3, "#778a91");
box(20, 20, 3, 28, 28, 4, "#91a2a7");
for (const x of [19, 27]) {
for (const y of [19, 27]) {
box(x, y, 0, x + 2, y + 2, 2, "#6b7e86");
box(x, y, 2, x + 2, y, 2, "#a9b6b8");
}
}
// Pierced bottom, with a stronger circular edge.
for (let x = 17; x <= 31; x++) {
for (let y = 17; y <= 31; y++) {
const d = Math.hypot(x - 24, y - 24);
if (d <= 7.3 && (d > 5.5 || x % 3 === 0 || y % 3 === 0)) {
set(x, y, 5, steel(x, y, 5));
}
}
}
// Horizontal hoops and closely spaced vertical ribs leave square openings.
for (let z = 6; z <= 29; z++) {
const r = radius(z);
for (let x = 4; x <= 44; x++) {
for (let y = 4; y <= 44; y++) {
const dx = x - 24, dy = y - 24;
const d = Math.hypot(dx, dy);
if (Math.abs(d - r) > 0.85) continue;
let angle = Math.atan2(dy, dx);
if (angle < 0) angle += Math.PI * 2;
const rib = (angle * 48 / (Math.PI * 2) + 0.17) % 1;
const hoop = z % 4 === 0 || z <= 7 || z >= 28;
if (hoop || rib < 0.42) {
set(x, y, z, steel(x, y, z, hoop ? 0.15 : -0.15));
}
}
}
}
// Thick, continuous rolled lip around the open mouth.
for (let z = 29; z <= 32; z++) {
for (let x = 4; x <= 44; x++) {
for (let y = 4; y <= 44; y++) {
const d = Math.hypot(x - 24, y - 24);
const inner = z === 32 ? 17.35 : 17.8;
const outer = z === 30 ? 19.3 : 19.7;
if (d >= inner && d <= outer) {
set(x, y, z, steel(x, y, z, z === 32 ? 1.25 : 0.45));
}
}
}
}
// Two flat, open-loop lifting handles, joined to opposite sides of the rim.
for (const [x0, x1] of [[2, 9], [39, 46]]) {
for (let x = x0; x <= x1; x++) {
for (let y = 20; y <= 28; y++) {
const border = x <= x0 + 1 || x >= x1 - 1 ||
y <= 21 || y >= 27;
if (!border) continue;
set(x, y, 30, steel(x, y, 30, 0.5));
set(x, y, 31, steel(x, y, 31, 1));
}
}
// Solid neck at the attachment point.
const a = x0 < 24 ? 8 : 39;
box(a, 22, 29, a + 1, 26, 31, "#aebbbd");
}
// Sparse bright glints emphasize the woven metal without obscuring the holes.
forEach((x, y, z, color) => {
if (z >= 8 && z <= 28 && rand() < 0.035) {
set(x, y, z, "#c1cbcb");
}
});import { draw } from "./assets/voxel";
import { colador } from "./assets/colador";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, colador, 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 colador
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["colador"] })
# Queda en client/assets/colador.ts
# https://fogon.page/object/colador