← City3D assetfogon/shipping-container-long
Contenedor largo
Drag to turn it// «Contenedor largo» · propio
// A 40-foot steel shipping container, deep blue, long and low in the grid, corrugated sides, darker frame, double doors with lock bars at one end.
// A 40-foot shipping container, long and low. Its length runs left to right (x); the doors are at the left end.
const BLUE = {
base: "#2f5f9e", light: "#3a70b3", dark: "#254c80", groove: "#1b3a63", top: "#4a82c4", frame: "#22477a", frameTop: "#2a5690",
rust: "#6b4a35", rust2: "#8a5a3a", casting: "#3d3f44", steel: "#c4c0b8", steelDark: "#85827c", seam: "#122a49",
};
// A container L long, W wide (odd, so the doors meet in the middle) and H high, with a frame F thick. `put(u, v, w, color)`
// places a block u along its length (0 at the doors), v across and w up. The walls are corrugated: every third column
// is set back one block.
function container(put, L, W, H, F, C, bars) {
const mid = (W - 1) / 2;
const side = (u, w) => {
if (u % 3 === 0) return null;
if (w < 2 + (u % 5 === 0 ? 1 : 0) && rand() < 0.5) return C.dark; // grime near the ground
if (rand() < 0.035) return rand() < 0.5 ? C.rust : C.rust2;
return u % 3 === 1 ? C.light : C.base;
};
const door = (v, w) => {
if (v === mid) return C.seam;
if ((v === F || v === W - 1 - F) && (w === F + 1 || w === Math.floor(H / 2) || w === H - 2 - F)) return C.casting; // hinges
return rand() < 0.03 ? C.rust : C.base;
};
for (let u = 0; u < L; u++)
for (let v = 0; v < W; v++)
for (let w = 0; w < H; w++) {
const du = Math.min(u, L - 1 - u), dv = Math.min(v, W - 1 - v), dw = Math.min(w, H - 1 - w);
const depth = Math.min(du, dv, dw);
if (depth > 1) continue; // hollow
const frame = (du < F && dv < F) || (dw < F && dv < F) || (dw < F && du < F);
let c;
if (du <= F && dv <= F && dw <= F) c = C.casting; // the corner blocks cranes grab
else if (frame) c = w >= H - F ? C.frameTop : C.frame;
else if (depth === 1) c = C.groove; // seen only through the grooves
else if (dw === 0) c = w === 0 ? C.frame : u % 3 === 0 ? null : rand() < 0.06 ? C.light : C.top;
else if (du === 0 && u === 0) c = door(v, w);
else if (du === 0) c = (v - F) % 3 === 0 ? null : (v - F) % 3 === 1 ? C.light : C.base;
else c = side(u, w);
if (c) put(u, v, w, c);
}
// Lock bars on the doors, with their brackets and handles.
const grip = Math.floor(H * 0.4);
for (const v of bars) {
for (let w = F; w <= H - 1 - F; w++) put(-1, v, w, w === F || w === H - 1 - F ? C.steelDark : C.steel);
}
put(-1, bars[0] + 1, grip, C.steelDark);
put(-1, bars[3] - 1, grip, C.steelDark);
// Rust running down from the roof rail.
for (let n = 0; n < 12; n++) {
const u = F + 1 + Math.floor(rand() * (L - 2 * F - 2));
if (u % 3 === 0) continue;
const v = rand() < 0.5 ? 0 : W - 1;
for (let k = 0; k < 1 + Math.floor(rand() * 3); k++) put(u, v, H - 1 - F - k, k ? C.rust : C.rust2);
}
}
const L = 45, W = 11, H = 12;
const X0 = 2, Y0 = 19;
container((u, v, w, c) => set(X0 + u, Y0 + v, w, c), L, W, H, 1, BLUE, [3, 3, 7, 7]); // one lock bar per door: the end is narrow
// A paler band along the top of the long sides, like a repainted panel (no letters).
for (let x = X0 + 8; x <= X0 + 15; x++) {
if ((x - X0) % 3 === 0) continue;
for (let z = 7; z <= 9; z++) { set(x, Y0, z, "#d9dde2"); set(x, Y0 + W - 1, z, "#d9dde2"); }
}import { draw } from "./assets/voxel";
import { shippingContainerLong } from "./assets/shipping-container-long";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, shippingContainerLong, x, y, { size: 64, angle: 0, t: performance.now() / 1000 });
// size: its longest side, in px
// angle: turn on the floor, in radians
// t: seconds; if it moves, that animates it# In a terminal, in the game's folder
fogon assets add shipping-container-long
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["shipping-container-long"] })
# It lands in client/assets/shipping-container-long.ts
# https://fogon.gg/object/shipping-container-long