🎮ArcadeLab

汉阳造步枪 - 比例校正版

by TurboKoala83
304 lines8.9 KB
▶ Play
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>汉阳造步枪 - 比例校正版</title>
<style>
  body { margin: 0; background: #1a1a2e; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; font-family: 'Microsoft YaHei', sans-serif; }
  canvas { background: linear-gradient(180deg, #16213e 0%, #0f3460 100%); border-radius: 12px; box-shadow: 0 0 40px rgba(196, 30, 58, 0.3); }
  .info { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); color: #c41e3a; font-size: 14px; letter-spacing: 4px; text-shadow: 0 0 10px rgba(196, 30, 58, 0.8); }
</style>
</head>
<body>
<div class="info">★ 汉阳造步枪 · 比例校正版 ★</div>
<canvas id="game" width="800" height="500"></canvas>

<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');

// ========== 配色 ==========
const GUN_COLORS = {
  wood:       '#6B4A2A', // 枪托木质主色(比之前更暖)
  woodDark:   '#4A2E15', // 木质阴影
  woodLite:   '#8B6A4A', // 木质高光
  metal:      '#5A5A5A', // 金属主色
  metalDark:  '#333333', // 金属阴影
  metalLite:  '#9A9A9A', // 金属高光
  strap:      '#7A6A4A', // 枪背带
};

function roundRect(ctx, x, y, w, h, r) {
  ctx.beginPath();
  ctx.moveTo(x + r, y);
  ctx.lineTo(x + w - r, y);
  ctx.quadraticCurveTo(x + w, y, x + w, y + r);
  ctx.lineTo(x + w, y + h - r);
  ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
  ctx.lineTo(x + r, y + h);
  ctx.quadraticCurveTo(x, y + h, x, y + h - r);
  ctx.lineTo(x, y + r);
  ctx.quadraticCurveTo(x, y, x + r, y);
  ctx.closePath();
}

// =====================================================================
// 汉阳造步枪 - 比例校正版
// 原点 (0,0) 在【扳机位置】
// 比例参考:全长1250mm,枪管740mm,约1.7:1
// 代码中:枪托后部到枪口约 340px,枪管约 200px
// =====================================================================
function drawRifle(ctx, x, y, rotation = 0, scale = 1) {
  ctx.save();
  ctx.translate(x, y);
  ctx.rotate(rotation);
  ctx.scale(scale, scale);

  const C = GUN_COLORS;

  // ---------------------------------------------------------
  // 1. 枪托后部(木质)- 从扳机向后延伸
  // ---------------------------------------------------------
  ctx.fillStyle = C.wood;
  ctx.beginPath();
  ctx.moveTo(-10, -5);     // 顶部靠前
  ctx.lineTo(-80, -8);     // 顶部靠后(枪托上沿)
  ctx.lineTo(-95, 8);      // 底部靠后(枪托下沿)
  ctx.lineTo(-60, 18);     // 底部靠前(握把上方)
  ctx.lineTo(-15, 12);     // 底部前段
  ctx.closePath();
  ctx.fill();

  // 枪托木质纹理与立体感
  ctx.fillStyle = C.woodDark;
  ctx.fillRect(-95, -8, 80, 3); // 顶部阴影
  ctx.fillStyle = C.woodLite;
  ctx.fillRect(-95, 5, 80, 2);  // 底部高光

  // 枪托后部的金属托底板
  ctx.fillStyle = C.metalDark;
  ctx.beginPath();
  ctx.moveTo(-95, -8);
  ctx.lineTo(-100, -6);
  ctx.lineTo(-100, 10);
  ctx.lineTo(-95, 8);
  ctx.closePath();
  ctx.fill();

  // 枪托中间的握把凹陷(更符合人体工学)
  ctx.fillStyle = C.woodDark;
  ctx.beginPath();
  ctx.arc(-40, 14, 12, 0, Math.PI, true);
  ctx.fill();

  // ---------------------------------------------------------
  // 2. 握把与扳机
  // ---------------------------------------------------------
  ctx.fillStyle = C.wood;
  ctx.beginPath();
  ctx.moveTo(-15, 10);
  ctx.lineTo(-5, 10);
  ctx.lineTo(-2, 40);
  ctx.lineTo(-12, 40);
  ctx.closePath();
  ctx.fill();

  ctx.fillStyle = C.woodDark;
  ctx.fillRect(-13, 10, 4, 30);

  // 扳机护圈
  ctx.strokeStyle = C.metal;
  ctx.lineWidth = 3;
  ctx.beginPath();
  ctx.arc(-4, 12, 9, 0, Math.PI);
  ctx.stroke();

  // ---------------------------------------------------------
  // 3. 枪身中部 - 木质前护木
  // ---------------------------------------------------------
  ctx.fillStyle = C.wood;
  ctx.fillRect(-10, -10, 110, 20); // 护木主体

  // 护木立体感
  ctx.fillStyle = C.woodLite;
  ctx.fillRect(-10, -10, 110, 3); // 顶部高光
  ctx.fillStyle = C.woodDark;
  ctx.fillRect(-10, 7, 110, 3);   // 底部阴影

  // ---------------------------------------------------------
  // 4. 枪管(金属)- 关键比例修正
  // ---------------------------------------------------------
  const barrelStart = 100;
  const barrelLength = 200; // 显著加长

  ctx.fillStyle = C.metal;
  ctx.fillRect(barrelStart, -6, barrelLength, 12);

  // 枪管高光与阴影(让金属有圆柱感)
  ctx.fillStyle = C.metalLite;
  ctx.fillRect(barrelStart, -5, barrelLength, 3);
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(barrelStart, 4, barrelLength, 2);

  // 枪管上的金属箍(老式步枪的特征)
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(barrelStart + 60, -8, 8, 16);  // 前箍
  ctx.fillRect(barrelStart + 130, -8, 8, 16); // 后箍

  // ---------------------------------------------------------
  // 5. 机匣与枪栓
  // ---------------------------------------------------------
  // 机匣底座
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(15, -12, 30, 24);

  // 枪栓拉柄 - 平直、球形头部(汉阳造特征)
  ctx.fillStyle = C.metalLite;
  ctx.beginPath();
  ctx.moveTo(25, -10);
  ctx.lineTo(30, -20);
  ctx.lineTo(38, -20);
  ctx.lineTo(32, -10);
  ctx.closePath();
  ctx.fill();

  // 枪栓球形把手
  ctx.fillStyle = C.metal;
  ctx.beginPath();
  ctx.arc(38, -20, 6, 0, Math.PI * 2);
  ctx.fill();

  ctx.fillStyle = C.metalLite;
  ctx.beginPath();
  ctx.arc(37, -21, 3, 0, Math.PI * 2);
  ctx.fill();

  // ---------------------------------------------------------
  // 6. 表尺照门(汉阳造特征:立框式表尺)
  // ---------------------------------------------------------
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(50, -18, 12, 8); // 表尺底座

  ctx.fillStyle = C.metal;
  ctx.fillRect(54, -28, 4, 10); // 表尺立框

  // 照门缺口
  ctx.fillStyle = '#1A1A1A';
  ctx.fillRect(55, -28, 2, 4);

  // ---------------------------------------------------------
  // 7. 枪口与准星
  // ---------------------------------------------------------
  const muzzleX = barrelStart + barrelLength;

  // 枪口
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(muzzleX - 6, -8, 6, 16);

  // 准星底座
  ctx.fillStyle = C.metal;
  ctx.fillRect(muzzleX - 20, -14, 8, 8);

  // 刀片形准星
  ctx.fillStyle = C.metalLite;
  ctx.beginPath();
  ctx.moveTo(muzzleX - 16, -14);
  ctx.lineTo(muzzleX - 12, -14);
  ctx.lineTo(muzzleX - 14, -22);
  ctx.closePath();
  ctx.fill();

  // ---------------------------------------------------------
  // 8. 刺刀 - 长度修正
  // ---------------------------------------------------------
  const bayonetLength = 80;

  // 刺刀座
  ctx.fillStyle = C.metalDark;
  ctx.fillRect(muzzleX - 4, -4, 8, 12);

  // 刺刀刀身
  ctx.fillStyle = C.metalLite;
  ctx.beginPath();
  ctx.moveTo(muzzleX, -3);
  ctx.lineTo(muzzleX + bayonetLength, -1);
  ctx.lineTo(muzzleX + bayonetLength + 5, 0);
  ctx.lineTo(muzzleX + bayonetLength, 1);
  ctx.lineTo(muzzleX, 3);
  ctx.closePath();
  ctx.fill();

  // 血槽
  ctx.fillStyle = '#FFFFFF';
  ctx.fillRect(muzzleX + 10, -1, bayonetLength - 20, 1);

  // ---------------------------------------------------------
  // 9. 枪背带(帆布)
  // ---------------------------------------------------------
  ctx.strokeStyle = C.strap;
  ctx.lineWidth = 5;
  ctx.beginPath();
  ctx.moveTo(-80, 10);
  ctx.quadraticCurveTo(-40, 55, 20, 25);
  ctx.lineTo(60, -8);
  ctx.stroke();

  // 背带环
  ctx.fillStyle = C.metalDark;
  ctx.beginPath();
  ctx.arc(-80, 10, 4, 0, Math.PI * 2);
  ctx.fill();
  ctx.beginPath();
  ctx.arc(60, -8, 4, 0, Math.PI * 2);
  ctx.fill();

  ctx.restore();
}

// =====================================================================
// 主循环
// =====================================================================
let time = 0;

function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  time += 0.02;

  const cx = canvas.width / 2;
  const cy = canvas.height / 2;

  // 参考线
  ctx.strokeStyle = '#2a4a3a';
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(0, cy + 60);
  ctx.lineTo(canvas.width, cy + 60);
  ctx.stroke();

  // 背景网格
  ctx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
  ctx.lineWidth = 1;
  for (let i = 0; i < canvas.width; i += 50) {
    ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, canvas.height); ctx.stroke();
  }
  for (let i = 0; i < canvas.height; i += 50) {
    ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvas.width, i); ctx.stroke();
  }

  // 绘制枪械(居中,整体向左偏移,因为枪管很长)
  drawRifle(ctx, cx - 60, cy, 0, 1.3);

  // 标注
  ctx.fillStyle = '#aaa';
  ctx.font = '12px sans-serif';
  ctx.fillText('原点 (0,0) 在扳机处', cx - 200, cy + 90);
  ctx.fillText('枪管长度: 200px (比例校正)', cx + 60, cy + 90);
  ctx.fillText('刺刀: 80px', cx + 260, cy + 90);

  requestAnimationFrame(animate);
}

animate();
</script>
</body>
</html>

Game Source: 汉阳造步枪 - 比例校正版

Creator: TurboKoala83

Libraries: none

Complexity: complex (304 lines, 8.9 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-turbokoala83-mup1d4kd" to link back to the original. Then publish at arcadelab.ai/publish.