← BásicoObjeto 3Dfogon/mesita-tripode
Mesita trípode
Arrastrá para girarlo// «Mesita trípode» · gpt-6-sol (medium)
// Tripod side table («Mesita trípode»).
// Tripod side table: warm plank top, three splayed legs, a book and a metal cup.
const wood = ["#d99655", "#dfa05f", "#e5a665", "#e9ad6d"];
const rim = ["#9b6137", "#a96a3b", "#b57442", "#c1824a"];
const cx = 24, cy = 24;
// Three chunky, slightly splayed wooden legs.
const legs = [
{ top: [20, 15], foot: [18, 11] }, // front
{ top: [11, 29], foot: [9, 32] },
{ top: [37, 29], foot: [40, 32] }
];
for (const leg of legs) {
for (let z = 0; z <= 33; z++) {
const t = z / 33;
const x = Math.round(leg.foot[0] * (1 - t) + leg.top[0] * t);
const y = Math.round(leg.foot[1] * (1 - t) + leg.top[1] * t);
const w = z > 27 ? 2 : 1;
for (let dx = -1; dx <= w; dx++)
for (let dy = -1; dy <= 1; dy++) {
const c = dx === -1 ? "#a3683b"
: dy === 1 ? "#925b34"
: (rand() < 0.15 ? "#c38a4e" : "#b37740");
set(x + dx, y + dy, z, c);
}
if (z > 4 && z < 31 && z % 5 === 1) {
set(x - 1, y - 2, z, "#d09352");
if (rand() < 0.55) set(x + 1, y - 2, z + 1, "#89552f");
}
}
const fx = leg.foot[0], fy = leg.foot[1];
box(fx - 1, fy - 1, 0, fx + 1, fy + 1, 1, "#d7ae6a");
box(fx - 1, fy - 1, 2, fx + 1, fy, 3, "#ae7842");
}
// Thick, softly irregular round tabletop.
for (let y = 4; y <= 44; y++) for (let x = 4; x <= 44; x++) {
const d = Math.hypot(x - cx, y - cy);
const wobble = 0.32 * Math.sin(x * 1.7 + y * 0.8);
if (d > 19.2 + wobble) continue;
set(x, y, 32, d > 17.7 ? "#89542f" : "#aa6a3b");
set(x, y, 33, d > 17.8 ? rim[(x + y) % rim.length] : "#b77843");
set(x, y, 34, d > 18 ? "#be7b43" : "#ce8c4d");
if (d < 18.6) {
const seam = (y + 2) % 5 === 0;
const shade = wood[Math.floor((y + 2) / 5) % wood.length];
set(x, y, 35, seam ? "#cb874b" : shade);
if (!seam && rand() < 0.075)
set(x, y, 35, rand() < 0.6 ? "#efb678" : "#ce8b4d");
}
}
// Little blocky scallops and shadows along the exposed edge.
for (let a = 0; a < 360; a += 9) {
const r = 18.5;
const x = Math.round(cx + Math.cos(a * Math.PI / 180) * r);
const y = Math.round(cy + Math.sin(a * Math.PI / 180) * r);
set(x, y, 33, y < 24 ? "#945b31" : "#b57440");
}
// Long, fine grain marks across the planks.
for (let i = 0; i < 115; i++) {
const x = 7 + Math.floor(rand() * 34);
const y = 7 + Math.floor(rand() * 34);
if (Math.hypot(x - cx, y - cy) < 17.5 && get(x, y, 35)) {
const c = rand() < 0.55 ? "#edb473" : "#cb874b";
const len = 1 + Math.floor(rand() * 5);
for (let j = 0; j < len; j++)
if (Math.hypot(x + j - cx, y - cy) < 17.5) set(x + j, y, 35, c);
}
}
// Small closed teal book, with its cream page edges visible at the front.
box(12, 19, 36, 22, 25, 37, "#153e40");
box(13, 18, 37, 21, 19, 38, "#d6ccab");
box(12, 18, 36, 22, 18, 36, "#0e3437");
box(11, 19, 38, 23, 25, 39, "#18565a");
box(12, 19, 40, 22, 24, 40, "#247477");
box(12, 19, 40, 12, 24, 40, "#34888a");
box(12, 25, 38, 22, 25, 39, "#103b3f");
box(16, 20, 41, 19, 20, 41, "#e3d2a0");
set(20, 22, 41, "#e8d9ab");
set(21, 22, 41, "#e8d9ab");
// Silver-white fluted cup, hollow and dark inside.
const mx = 32, my = 29;
for (let z = 36; z <= 43; z++) {
for (let y = my - 3; y <= my + 3; y++)
for (let x = mx - 3; x <= mx + 3; x++) {
const d = Math.hypot(x - mx, y - my);
if (d <= 3.4 && d >= 1.8) {
const stripe = (x + 2 * y) % 3;
const color = x < mx - 1 ? "#f1e9d8"
: stripe === 0 ? "#c0b9a9"
: stripe === 1 ? "#ddd6c6" : "#eee6d5";
set(x, y, z, color);
}
}
}
for (let y = my - 2; y <= my + 2; y++)
for (let x = mx - 2; x <= mx + 2; x++)
if (Math.hypot(x - mx, y - my) < 2.5)
set(x, y, 41, "#645c50");
for (let y = my - 3; y <= my + 3; y++)
for (let x = mx - 3; x <= mx + 3; x++) {
const d = Math.hypot(x - mx, y - my);
if (d >= 2 && d <= 3.5)
set(x, y, 44, y < my ? "#f3ecdf" : "#c5bfb1");
}
set(mx - 1, my, 43, "#413c36");
set(mx, my + 1, 43, "#716a5e");
set(mx + 1, my, 43, "#514c43");import { draw } from "./assets/voxel";
import { mesitaTripode } from "./assets/mesita-tripode";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, mesitaTripode, 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 mesita-tripode
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["mesita-tripode"] })
# Queda en client/assets/mesita-tripode.ts
# https://fogon.page/object/mesita-tripode