← ArmasObjeto 3Dfogon/arma-lanzagranadas
Lanzagranadas
Arrastrá para girarlo// «Lanzagranadas» · propio
// A chunky grenade launcher with a big revolving drum and a fat short barrel, green and black.
const colors = () => {};
const G1 = "#2b3520", G2 = "#3c4a2c", G3 = "#52633a", G4 = "#6b7f4c";
const K1 = "#0e0f12", K2 = "#1b1e23", K3 = "#2f353d", K4 = "#4a515a";
const O1 = "#a83f18", O2 = "#dd7a33";
// ================= BODY =================
// ---- buttstock ----
box(2,19,0, 3,29,13, K2); // rubber butt pad
box(4,20,1, 7,28,12, G2); // stock body
box(4,21,11, 7,27,12, G3); // stock top highlight
box(4,20,1, 7,28,2, G1); // stock underside shadow
box(6,20,6, 7,28,9, G1); // side grain shadow
box(8,19,2, 9,29,13, G2); // stock -> receiver collar
// ---- receiver ----
box(9,18,3, 19,30,13, G2);
box(9,18,12, 19,30,13, G3); // top plate lighter
box(9,18,3, 19,30,4, G1); // belly shadow
box(9,18,5, 9,30,11, G1); // rear face shadow
box(11,18,6, 18,18,11, G1); // side panel (near)
box(11,30,6, 18,30,11, G1); // side panel (far)
box(13,18,9, 17,18,10, O1); // warning stripe near
box(13,30,9, 17,30,10, O1); // warning stripe far
// ---- top rail ----
box(11,23,14, 18,25,14, K2);
box(12,23,14, 17,23,14, K3);
// ---- pistol grip ----
box(12,21,0, 16,27,4, K2);
box(12,21,0, 16,21,4, K3);
box(12,27,0, 16,27,4, K3);
box(12,22,0, 16,26,1, K1);
// ---- trigger guard + trigger ----
box(17,22,0, 19,22,3, K2);
box(17,26,0, 19,26,3, K2);
box(17,22,0, 19,26,0, K2);
box(18,23,2, 19,25,3, K3);
// ---- barrel ----
cylinder(32,24,7, 4, 9, K3, "x"); // x 32..40
cylinder(35,24,7, 5, 1, K2, "x"); // cooling rib
cylinder(38,24,7, 5, 1, K2, "x"); // cooling rib
box(32,23,11, 40,25,11, K4); // top highlight
// ---- muzzle brake ----
cylinder(41,24,7, 5, 4, K3, "x"); // x 41..44
cylinder(44,24,7, 5, 1, K4, "x"); // bright front ring
cylinder(42,24,7, 2.6, 3, K1, "x"); // bore
// ---- front sight ----
box(38,23,11, 39,25,14, K2);
box(38,24,14, 39,24,14, K3);
// subtle green grain on body
forEach((x, y, z, c) => {
if (c === G2 && rand() < 0.16) set(x, y, z, G3);
else if (c === G2 && rand() < 0.10) set(x, y, z, G1);
else if (c === K3 && rand() < 0.14) set(x, y, z, K4);
});
// ================= REVOLVING DRUM =================
part("drum", [26, 24, 7]);
cylinder(20,24,7, 7, 12, G2, "x"); // x 20..31
cylinder(20,24,7, 7, 1, G1, "x"); // rear cap
cylinder(31,24,7, 7, 1, G3, "x"); // front cap
// chamber flutes + grenade noses, following the drum's radial symmetry
forEach((x, y, z, c) => {
if (x < 21 || x > 30) return;
const dy = y - 24, dz = z - 7;
const r = Math.sqrt(dy * dy + dz * dz);
if (r < 5.2) return;
if (x <= 21 || x >= 30) { set(x, y, z, G1); return; }
const a = Math.atan2(dz, dy);
let best = Math.PI;
for (let k = 0; k < 6; k++) {
let d = Math.abs(a - k * Math.PI / 3);
if (d > Math.PI) d = 2 * Math.PI - d;
if (d < best) best = d;
}
if (best < 0.13) {
set(x, y, z, (x >= 23 && x <= 28) ? O2 : K1);
} else if (best < 0.30) {
set(x, y, z, K1);
} else if (r > 6.3 && rand() < 0.5) {
set(x, y, z, G4);
}
});
animate("drum", { type: "spin", axis: "x", speed: 0.7 });import { draw } from "./assets/voxel";
import { armaLanzagranadas } from "./assets/arma-lanzagranadas";
// En cada cuadro: parado sobre (x, y), el centro de su base.
draw(ctx, armaLanzagranadas, 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 arma-lanzagranadas
# Con las herramientas de Fogón (conector)
add_assets({ slug: "<tu-juego>", ids: ["arma-lanzagranadas"] })
# Queda en client/assets/arma-lanzagranadas.ts
# https://fogon.page/object/arma-lanzagranadas