← Weapons3D assetfogon/arma-bumeran
Bumerán
Drag to turn it// «Bumerán» · propio
// A wooden boomerang, V shape with painted red and white stripes.
const colors = () => {};
part("boomerang", [24, 23, 0]);
const EX = 24, EY = 35; // vertex / grip (back, +y)
const AX = 12, AY = 10; // tip A (front-left, -y)
const BX = 36, BY = 10; // tip B (front-right, -y)
const CZ = 2.5; // vertical center
const RAD = 3.0; // half-thickness of the blade
// ---- raw wooden V shape -------------------------------------------------
line(EX, EY, CZ, AX, AY, CZ, RAD, "#8b5a2b");
line(EX, EY, CZ, BX, BY, CZ, RAD, "#8b5a2b");
sphere(EX, EY, CZ, RAD, "#8b5a2b");
// ---- helper: closest-point on a segment --------------------------------
function segInfo(px, py, x0, y0, x1, y1) {
const dx = x1 - x0, dy = y1 - y0;
const L2 = dx * dx + dy * dy;
let t = ((px - x0) * dx + (py - y0) * dy) / L2;
t = Math.max(0, Math.min(1, t));
const qx = x0 + t * dx, qy = y0 + t * dy;
return [Math.hypot(px - qx, py - qy), t * Math.sqrt(L2)];
}
// ---- palette: 3 shades per material ------------------------------------
const SHADES = {
"#c8302a": ["#9a221e", "#c8302a", "#e8544a"], // red paint
"#f2ece0": ["#cfc5b4", "#f2ece0", "#ffffff"], // white paint
"#a9713a": ["#6b4320", "#a9713a", "#c9955e"], // light wood
"#6b4320": ["#4a2d15", "#6b4320", "#8b5a2b"] // dark wood / cord wrap
};
// ---- paint pass: grip wrap at vertex, red/white bands along the arms ---
const cells = [];
forEach((x, y, z) => { cells.push([x, y, z]); });
for (let i = 0; i < cells.length; i++) {
const x = cells[i][0], y = cells[i][1], z = cells[i][2];
const dE = Math.hypot(x - EX, y - EY);
let base;
if (dE < 7) {
// wrapped cord grip around the vertex
const ring = Math.floor(dE / 1.7) % 2;
base = ring ? "#6b4320" : "#a9713a";
} else {
const pa = segInfo(x, y, EX, EY, AX, AY);
const pb = segInfo(x, y, EX, EY, BX, BY);
const t = pa[0] <= pb[0] ? pa[1] : pb[1];
const s = t - 7.5;
if (s < 0) {
base = "#a9713a";
} else {
const band = Math.floor(s / 5.5);
base = (band % 2 === 0) ? "#c8302a" : "#f2ece0";
}
}
// shade by surface facing: bright top, mid sides, dark underside
const pal = SHADES[base];
let idx = 1;
if (get(x, y, z + 1) === undefined) idx = 2;
else if (get(x, y, z - 1) === undefined) idx = 0;
set(x, y, z, pal[idx]);
}
// ---- idle motion: the whole boomerang slowly spins flat on the floor ----
animate("boomerang", { type: "spin", axis: "z", speed: 1.0 });import { draw } from "./assets/voxel";
import { armaBumeran } from "./assets/arma-bumeran";
// Every frame: standing on (x, y), the centre of its base.
draw(ctx, armaBumeran, 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-bumeran
# With Fogón's tools (connector)
add_assets({ slug: "<your-game>", ids: ["arma-bumeran"] })
# It lands in client/assets/arma-bumeran.ts
# https://fogon.page/object/arma-bumeran