← CiudadObjeto 3Dfogon/shelf-rack
Estantería de depósito
Arrastrá para girarlo// «Estantería de depósito» · propio
// A warehouse pallet rack: blue steel uprights and orange beams, three levels holding cardboard boxes, a crate and a few barrels.
// A warehouse pallet rack: blue uprights, orange beams, three levels with a crate, barrels and cardboard boxes.
const BLUE = { base: "#2f5fae", light: "#4478c9", dark: "#234a8a" };
const ORANGE = { base: "#f08a24", light: "#f9a547", dark: "#c66c13" };
const DECK = ["#d9c49a", "#cdb78b", "#c1aa7d"];
const CARD = [
{ base: "#c9a26b", top: "#dbb981", dark: "#a8844f", tape: "#ecdcb4" },
{ base: "#bd9560", top: "#d0ab75", dark: "#9c7946", tape: "#e6d5aa" },
{ base: "#d2ae79", top: "#e2c28f", dark: "#b18f5b", tape: "#f1e4c2" },
];
const WOOD = { plank: ["#b9803f", "#c68d49"], groove: "#8a5a28", frame: "#9c6730", frameLight: "#b98040", frameDark: "#744a20" };
// The two end frames: two posts each, with holes punched up their fronts, tied by struts in a zigzag.
for (const x of [3, 43]) {
for (const y of [17, 29]) {
box(x, y, 0, x + 1, y + 1, 45, BLUE.base);
box(x, y, 0, x, y, 45, BLUE.light);
for (let z = 2; z <= 44; z += 3) set(x + 1, y, z, BLUE.dark);
box(x - 1, y - 1, 0, x + 2, y + 2, 0, "#5b6068");
}
const sx = x === 3 ? 3 : 44;
const levels = [6, 16, 26, 36, 44];
for (const z of levels) box(sx, 19, z, sx, 28, z, BLUE.base);
for (let n = 0; n + 1 < levels.length; n++) {
const up = n % 2 === 0;
line(sx, up ? 19 : 28, levels[n], sx, up ? 28 : 19, levels[n + 1], 0, BLUE.dark);
}
}
// The beams (front and back) and the boards across them, one set per level.
const levelsAt = [3, 17, 31];
for (const z of levelsAt) {
for (const y of [17, 30]) {
box(5, y === 17 ? 17 : 29, z, 42, y === 17 ? 18 : 30, z + 1, ORANGE.base);
box(5, y === 17 ? 17 : 29, z + 1, 42, y === 17 ? 18 : 30, z + 1, ORANGE.light);
for (const x of [5, 42]) box(x, y === 17 ? 17 : 30, z - 1, x, y === 17 ? 17 : 30, z + 2, ORANGE.dark); // the hooks
}
for (let x = 5; x <= 42; x++) if (x % 5 !== 4) box(x, 19, z + 1, x, 28, z + 1, DECK[Math.floor(x / 5) % 3]);
}
function carton(x0, y0, z0, w, d, h, kind) {
const C = CARD[kind];
for (let x = x0; x < x0 + w; x++)
for (let y = y0; y < y0 + d; y++)
for (let z = z0; z < z0 + h; z++) {
if (x > x0 && x < x0 + w - 1 && y > y0 && y < y0 + d - 1 && z < z0 + h - 1) continue;
let c = z === z0 + h - 1 ? C.top : z === z0 ? C.dark : rand() < 0.08 ? C.dark : C.base;
const mid = x0 + Math.floor(w / 2);
if ((x === mid || (w % 2 === 0 && x === mid - 1)) && z >= z0 + h - 3) c = C.tape; // the tape over the flaps
set(x, y, z, c);
}
}
function barrel(cx, cy, z0, r, h, base, light, dark) {
for (let z = z0; z < z0 + h; z++) {
const k = z - z0, hoop = k === 0 || k === h - 1 || k === Math.floor(h / 3) || k === Math.floor((2 * h) / 3);
for (let x = Math.floor(cx - r - 1); x <= cx + r + 1; x++)
for (let y = Math.floor(cy - r - 1); y <= cy + r + 1; y++) {
const d = Math.hypot(x - cx, y - cy);
if (d > r) continue;
set(x, y, z, k === h - 1 ? (d < r - 1.2 ? dark : light) : hoop ? dark : x < cx - 1 ? light : base);
}
}
set(Math.round(cx - 1), Math.round(cy - 1), z0 + h - 1, "#2a2c30"); // the bung
}
function crate(x0, y0, z0, w, d, h) {
for (let x = x0; x < x0 + w; x++)
for (let y = y0; y < y0 + d; y++)
for (let z = z0; z < z0 + h; z++) {
const ex = x === x0 || x === x0 + w - 1, ey = y === y0 || y === y0 + d - 1, ez = z === z0 || z === z0 + h - 1;
if (!ex && !ey && !ez) continue;
const edges = (ex ? 1 : 0) + (ey ? 1 : 0) + (ez ? 1 : 0);
const a = ex ? y - y0 : x - x0;
let c = a % 3 === 0 ? WOOD.groove : WOOD.plank[Math.floor(a / 3) % 2];
const fx = x - x0 < 2 || x0 + w - 1 - x < 2, fy = y - y0 < 2 || y0 + d - 1 - y < 2, fz = z - z0 < 2 || z0 + h - 1 - z < 2;
if ((fx ? 1 : 0) + (fy ? 1 : 0) + (fz ? 1 : 0) >= 2) c = z === z0 + h - 1 ? WOOD.frameLight : edges >= 2 ? WOOD.frameDark : WOOD.frame;
set(x, y, z, c);
}
}
// Bottom level: a crate and two barrels.
crate(6, 18, 5, 12, 11, 10);
barrel(24, 23.5, 5, 4.5, 11, "#2f6fb0", "#4a8bcc", "#235488");
barrel(35, 23.5, 5, 4.5, 11, "#b5462e", "#cf5f43", "#8c3421");
// Middle level: cardboard boxes, some stacked.
carton(6, 18, 19, 10, 10, 8, 0);
carton(7, 19, 27, 6, 7, 3, 2);
carton(17, 19, 19, 9, 10, 10, 1);
carton(27, 18, 19, 7, 8, 6, 2);
carton(28, 19, 25, 5, 6, 4, 0);
carton(35, 19, 19, 8, 10, 9, 0);
// Top level: more boxes and a barrel.
carton(6, 18, 33, 12, 11, 7, 1);
carton(8, 19, 40, 7, 8, 4, 0);
barrel(24.5, 23.5, 33, 4, 10, "#3f8f5a", "#58a973", "#2d6a43");
carton(31, 19, 33, 11, 9, 6, 2);
carton(33, 20, 39, 6, 7, 4, 1);import { draw } from "./assets/voxel";
import { shelfRack } from "./assets/shelf-rack";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, shelfRack, 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 shelf-rack
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["shelf-rack"] })
# Queda en client/assets/shelf-rack.ts
# https://fogon.gg/object/shelf-rack