← Weapons3D assetfogon/arma-ballesta
Ballesta
Drag to turn it// «Ballesta» · propio
// A wooden crossbow with a wide bow at the front, taut string and a loaded bolt.
const colors = () => {};
const W1="#3f2812", W2="#5d3b1c", W3="#7b5027", W4="#9a6835", W5="#b88448";
const M2="#4a4f5b", M3="#767d8b", M4="#a8b0bd";
const S2="#ded0aa";
const B2="#8f5a24";
const R2="#cd4a3c";
part("body");
// ---------------- STOCK ----------------
box(21, 19, 0, 27, 42, 4, W3); // main body
box(20, 38, 0, 28, 42, 3, W3); // butt flare
box(21, 39, 0, 27, 42, 5, W3); // butt step
box(22, 40, 0, 26, 42, 6, W3); // butt crown
box(22, 16, 0, 26, 18, 3, W3); // fore-end
// iron bands wrapping the stock
box(20, 24, 0, 28, 25, 4, M3);
box(20, 36, 0, 28, 37, 4, M3);
// ---------------- BOW (PROD) ----------------
for (let x = 4; x <= 44; x++) {
const t = (x - 24) / 20;
const yc = Math.round(18 - 8 * t * t);
box(x, yc - 1, 1, x, yc + 1, 4, W4);
}
// limb tip caps
box(3, 9, 1, 4, 11, 5, M3);
box(44, 9, 1, 45, 11, 5, M3);
// mounting bracket over the bow centre
box(21, 16, 4, 27, 20, 4, M3);
// ---------------- STRING (drawn back) ----------------
line(4, 10, 5, 24, 30, 5, 0, S2);
line(44, 10, 5, 24, 30, 5, 0, S2);
// ---------------- LOCK / NUT HOUSING ----------------
box(22, 31, 4, 26, 36, 5, M2);
box(23, 32, 6, 25, 35, 6, M3);
// ---------------- LOADED BOLT ----------------
part("bolt", [24, 20, 5]);
box(23, 12, 5, 25, 29, 6, B2); // shaft
box(24, 8, 5, 24, 8, 6, M4); // point
box(23, 9, 5, 25, 9, 6, M3);
box(22, 10, 5, 26, 10, 6, M3); // broadhead barbs
box(23, 11, 5, 25, 11, 6, M3);
box(22, 25, 5, 22, 29, 6, R2); // left vane
box(26, 25, 5, 26, 29, 6, R2); // right vane
box(23, 25, 7, 25, 29, 7, R2); // top vane
animate("bolt", { type: "bob", axis: "z", speed: 0.9, amplitude: 1 });
// ---------------- SHADING / GRAIN ----------------
part("body");
forEach((x, y, z, c) => {
if (c === W2 || c === W3 || c === W4 || c === W5) {
if (z === 0) { set(x, y, z, W1); return; }
if (!get(x, y, z + 1)) {
set(x, y, z, rand() < 0.78 ? W5 : W4);
return;
}
const r = rand();
if (r < 0.15) set(x, y, z, W2);
else if (r < 0.32) set(x, y, z, W4);
} else if (c === M2 || c === M3) {
if (!get(x, y, z + 1)) set(x, y, z, c === M3 ? M4 : M3);
}
});import { draw } from "./assets/voxel";
import { armaBallesta } from "./assets/arma-ballesta";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, armaBallesta, 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 arma-ballesta
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["arma-ballesta"] })
# It lands in client/assets/arma-ballesta.ts
# https://fogon.page/object/arma-ballesta