汉阳造步枪 - 独立建模测试
by TurboKoala83273 lines8.1 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="700" height="500"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
// ========== 枪械配色 ==========
const GUN_COLORS = {
wood: '#5A3A1A', // 枪托木质主色
woodDark: '#3A2210', // 木质阴影
woodLite: '#7A4A2A', // 木质高光
metal: '#4A4A4A', // 金属主色(枪管、机匣)
metalDark: '#2A2A2A', // 金属阴影
metalLite: '#8A8A8A', // 金属高光(枪栓、刺刀)
strap: '#6B5A3A', // 枪背带
};
// ========== 绘制工具 ==========
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) 设定在【扳机位置】(即右手握持处),方便后续挂载
// x 轴正方向为枪口方向(向右),y 轴正方向向下
// =====================================================================
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(-15, -5); // 顶部靠前
ctx.lineTo(-50, -5); // 顶部靠后
ctx.lineTo(-55, 10); // 底部靠后
ctx.lineTo(-25, 15); // 底部靠前(握把上方)
ctx.closePath();
ctx.fill();
// 枪托阴影和高光
ctx.fillStyle = C.woodDark;
ctx.beginPath();
ctx.moveTo(-15, -5);
ctx.lineTo(-50, -5);
ctx.lineTo(-50, 0);
ctx.lineTo(-15, 0);
ctx.closePath();
ctx.fill();
ctx.fillStyle = C.woodLite;
ctx.fillRect(-50, 0, 35, 2);
// 金属托底板
ctx.fillStyle = C.metalDark;
ctx.fillRect(-56, -6, 3, 20);
// ---------------------------------------------------------
// 2. 握把与扳机(木质握把)
// ---------------------------------------------------------
ctx.fillStyle = C.wood;
ctx.beginPath();
ctx.moveTo(-25, 10);
ctx.lineTo(-15, 10);
ctx.lineTo(-10, 35);
ctx.lineTo(-20, 35);
ctx.closePath();
ctx.fill();
ctx.fillStyle = C.woodDark;
ctx.fillRect(-22, 10, 4, 25);
// 扳机护圈(金属圆弧)
ctx.strokeStyle = C.metal;
ctx.lineWidth = 3;
ctx.beginPath();
ctx.arc(-10, 12, 8, 0, Math.PI);
ctx.stroke();
// ---------------------------------------------------------
// 3. 枪身中部(木质前护木)
// ---------------------------------------------------------
ctx.fillStyle = C.wood;
ctx.fillRect(-10, -8, 70, 16); // 从扳机前方延伸到枪管中段
// 木质高光和阴影
ctx.fillStyle = C.woodLite;
ctx.fillRect(-10, -8, 70, 3);
ctx.fillStyle = C.woodDark;
ctx.fillRect(-10, 5, 70, 3);
// ---------------------------------------------------------
// 4. 枪管(金属)
// ---------------------------------------------------------
const barrelLength = 90;
ctx.fillStyle = C.metal;
ctx.fillRect(40, -6, barrelLength, 12); // 主枪管
// 枪管高光与阴影
ctx.fillStyle = C.metalLite;
ctx.fillRect(40, -5, barrelLength, 3);
ctx.fillStyle = C.metalDark;
ctx.fillRect(40, 4, barrelLength, 2);
// ---------------------------------------------------------
// 5. 机匣与枪栓(金属结构)
// ---------------------------------------------------------
// 机匣底座
ctx.fillStyle = C.metalDark;
ctx.fillRect(5, -10, 15, 20);
// 枪栓拉柄
ctx.fillStyle = C.metalLite;
ctx.beginPath();
ctx.moveTo(12, -8);
ctx.lineTo(18, -15);
ctx.lineTo(22, -15);
ctx.lineTo(18, -8);
ctx.closePath();
ctx.fill();
// 枪栓圆球把手
ctx.fillStyle = C.metal;
ctx.beginPath();
ctx.arc(22, -15, 5, 0, Math.PI * 2);
ctx.fill();
// 枪栓高光
ctx.fillStyle = C.metalLite;
ctx.beginPath();
ctx.arc(21, -16, 2, 0, Math.PI * 2);
ctx.fill();
// ---------------------------------------------------------
// 6. 枪口与准星(金属)
// ---------------------------------------------------------
const muzzleX = 40 + barrelLength;
// 枪口
ctx.fillStyle = C.metalDark;
ctx.fillRect(muzzleX - 5, -7, 5, 14);
// 准星底座
ctx.fillStyle = C.metal;
ctx.fillRect(muzzleX - 15, -12, 6, 6);
// 准星
ctx.fillStyle = C.metalLite;
ctx.fillRect(muzzleX - 12, -16, 2, 4);
// ---------------------------------------------------------
// 7. 刺刀(锋利的金属)
// ---------------------------------------------------------
ctx.fillStyle = C.metalLite;
ctx.beginPath();
ctx.moveTo(muzzleX, -4); // 刀根下部
ctx.lineTo(muzzleX + 30, -3); // 刀尖下部
ctx.lineTo(muzzleX + 32, -1); // 刀尖
ctx.lineTo(muzzleX + 30, 0); // 刀尖上部
ctx.lineTo(muzzleX, 2); // 刀根上部
ctx.closePath();
ctx.fill();
// 刺刀血槽(反光线条)
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(muzzleX + 5, -1, 20, 1);
// 刺刀固定环
ctx.fillStyle = C.metalDark;
ctx.fillRect(muzzleX - 2, -6, 4, 12);
// ---------------------------------------------------------
// 8. 枪背带(帆布/皮革)
// ---------------------------------------------------------
ctx.strokeStyle = C.strap;
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(-45, 5); // 从枪托后部挂载
ctx.quadraticCurveTo(-20, 40, 20, 20); // 自然下垂
ctx.lineTo(30, -5); // 连接到前护木
ctx.stroke();
// 背带环(金属小圆)
ctx.fillStyle = C.metalDark;
ctx.beginPath();
ctx.arc(-45, 5, 3, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(30, -5, 3, 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 + 50);
ctx.lineTo(canvas.width, cy + 50);
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 - 20, cy, 0, 1.5);
// 绘制文字标注
ctx.fillStyle = '#aaa';
ctx.font = '12px sans-serif';
ctx.fillText('原点 (0,0) 在扳机处', cx - 100, cy + 80);
ctx.fillText('枪管长度: 90px', cx + 40, cy + 80);
ctx.fillText('刺刀: 30px', cx + 150, cy + 80);
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>Game Source: 汉阳造步枪 - 独立建模测试
Creator: TurboKoala83
Libraries: none
Complexity: complex (273 lines, 8.1 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-mup0voqh" to link back to the original. Then publish at arcadelab.ai/publish.