汉阳造步枪 - 比例校正版
by TurboKoala83304 lines8.9 KB
<!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-mup4bqyl" to link back to the original. Then publish at arcadelab.ai/publish.