fogón

← Weapons3D assetfogon/arma-rebotador

Rebotador

by fogonCC03921 blocks
RebotadorDrag to turn it
// «Rebotador» · propio
// A futuristic purple energy blaster with glowing violet coils and a crystal at the muzzle.

const colors = () => {};
// ===== palette =====
const DARK   = "#1a0f2e";
const BODY   = "#2e1c4f";
const BODY2  = "#3d2668";
const BODY3  = "#513589";
const TRIM   = "#b48ce8";
const METAL  = "#5d5170";
const METAL2 = "#8477a0";
const COIL_D = "#7a2fd0";
const COIL_M = "#b06bff";
const COIL_L = "#e6b8ff";
const CRYS_D = "#8a2be2";
const CRYS_M = "#c060ff";
const CRYS_L = "#f0c8ff";

// ===== helpers =====
function discYZ(x, cy, cz, r, color){
  for (let y = Math.floor(cy - r - 0.5); y <= Math.ceil(cy + r + 0.5); y++)
    for (let z = Math.floor(cz - r - 0.5); z <= Math.ceil(cz + r + 0.5); z++)
      if (Math.hypot(y - cy, z - cz) <= r) set(x, y, z, color);
}
function ringYZ(x, cy, cz, r, th, color){
  for (let y = Math.floor(cy - r - 1); y <= Math.ceil(cy + r + 1); y++)
    for (let z = Math.floor(cz - r - 1); z <= Math.ceil(cz + r + 1); z++){
      const d = Math.hypot(y - cy, z - cz);
      if (d <= r && d >= r - th) set(x, y, z, color);
    }
}

part("body");

// ===== main housing =====
box(9, 18, 1, 30, 30, 9, BODY);
box(9, 18, 1, 30, 30, 1, DARK);
box(9, 18, 9, 30, 30, 9, BODY2);

// top trim border
box(9, 18, 9,  9, 30, 9, TRIM);
box(30, 18, 9, 30, 30, 9, TRIM);
box(9, 30, 9, 30, 30, 9, TRIM);
box(9, 18, 9, 30, 18, 9, TRIM);

// rear block / back strap shading
box(9, 18, 2, 11, 30, 8, BODY3);

// side vents (far side)
for (let i = 0; i < 4; i++)
  box(14 + i * 3, 30, 4, 15 + i * 3, 30, 7, DARK);

// rear sight
box(10, 22, 10, 12, 26, 10, METAL2);
box(10, 23, 11, 12, 25, 11, METAL);

// top frame plate
box(13, 20, 9, 25, 28, 9, METAL);

// ===== collar between body and barrel =====
box(29, 20, 2, 32, 28, 8, BODY);
box(29, 20, 8, 32, 28, 8, BODY2);
box(29, 20, 2, 32, 28, 2, DARK);

// ===== barrel shroud =====
box(32, 22, 3, 40, 26, 7, BODY);
box(32, 22, 7, 40, 26, 7, BODY2);
box(32, 22, 3, 40, 26, 3, DARK);

// barrel tube
cylinder(38, 24, 5, 2, 5, BODY3, "x");

// front sight
box(38, 23, 8, 39, 25, 8, METAL2);

// ===== pistol grip =====
for (let y = 8; y <= 18; y++){
  const t  = (18 - y) / 10;
  const cx = 17 - 2.5 * t;
  const hw = 3.6 - 0.6 * t;
  const x0 = Math.round(cx - hw);
  const x1 = Math.round(cx + hw);
  for (let x = x0; x <= x1; x++)
    for (let z = 1; z <= 8; z++){
      let c = BODY;
      if (z === 8) c = BODY2;
      if (z === 1) c = DARK;
      if (x === x0 || x === x1) c = BODY3;
      set(x, y, z, c);
    }
}
// grip ridges
for (let y = 9; y <= 16; y += 2)
  box(12, y, 2, 20, y, 2, DARK);
// grip butt cap
box(12, 7, 1, 18, 7, 7, METAL);
box(12, 8, 1, 18, 8, 1, METAL2);

// ===== trigger guard =====
for (let a = 200; a <= 340; a += 3){
  const rad = a * Math.PI / 180;
  for (const rr of [6.5, 5.7]){
    const x = Math.round(24 + rr * Math.cos(rad));
    const y = Math.round(18 + rr * Math.sin(rad));
    for (let z = 2; z <= 5; z++) set(x, y, z, METAL);
  }
}
// trigger
box(21, 16, 3, 22, 17, 5, TRIM);

// ===== glowing energy cell =====
part("cell");
box(15, 22, 9, 23, 26, 10, CRYS_M);
box(15, 22, 10, 23, 22, 10, CRYS_L);
part("body");

// ===== violet coils =====
part("coils");
for (const bx of [33, 35, 37]){
  for (let xx = bx; xx < bx + 2; xx++)
    ringYZ(xx, 24, 5, 3.4, 1.6, COIL_M);
}
part("body");

// ===== muzzle crystal =====
part("crystal");
const crysR = [[41,1.4],[42,2.6],[43,3.0],[44,2.6],[45,1.6],[46,0.7]];
for (const p of crysR) discYZ(p[0], 24, 5, p[1], CRYS_D);
discYZ(43, 24, 5, 1.9, CRYS_M);
discYZ(44, 24, 5, 1.2, CRYS_L);
part("body");

// ===== floating energy orb =====
part("orb");
sphere(44, 24, 12, 2, CRYS_M);
sphere(44, 24, 12, 1, CRYS_L);

// ===== animation =====
colors("coils",   { palette: ["#7a2fd0", "#b06bff", "#e6b8ff", "#8a2be2"], pattern: "wave",    speed: 1.6, glow: 0.9 });
colors("crystal", { palette: ["#8a2be2", "#c060ff", "#f0c8ff", "#d97bff"], pattern: "swirl",   speed: 1.2, glow: 1.0 });
colors("cell",    { palette: ["#7a2fd0", "#c060ff", "#f0c8ff"],             pattern: "pulse",   speed: 2.0, glow: 0.8 });
colors("orb",     { palette: ["#c060ff", "#f0c8ff", "#8a2be2"],             pattern: "pulse",   speed: 1.4, glow: 1.0 });

void ("orb", { type: "bob", axis: "z", speed: 1.3, amplitude: 1.6 });

// Sit it on the floor (the lowest block was at z=1).
const __all = [];
forEach((x, y, z, c) => __all.push([x, y, z, c]));
for (const [x, y, z] of __all) set(x, y, z, null);
for (const [x, y, z, c] of __all) set(x, y, z - 1, c);