铁轮工会 · 原型
by EpicCoder88201 lines7.9 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>铁轮工会 · 原型</title>
<style>
body { margin: 0; overflow: hidden; background-color: #2c3e50; font-family: sans-serif; touch-action: none; }
canvas { display: block; }
#ui {
position: absolute; top: 10px; left: 10px; right: 10px; bottom: 10px;
pointer-events: none; display: flex; flex-direction: column; justify-content: space-between;
}
.panel {
background: rgba(0, 0, 0, 0.7); color: #fff; padding: 10px; border-radius: 8px;
font-size: 14px; line-height: 1.5; border: 1px solid #555;
}
.log { max-height: 100px; overflow-y: auto; font-size: 12px; color: #bdc3c7; }
.log p { margin: 2px 0; }
.stat { font-weight: bold; color: #f1c40f; }
</style>
</head>
<body>
<canvas id="gameCanvas"></canvas>
<!-- 游戏UI层 -->
<div id="ui">
<div class="panel">
<div>身份: <span id="role" class="stat">守法老公民</span></div>
<div>状态: <span id="status" class="stat">和平</span></div>
<div>行动力: <span id="energy" class="stat">100</span> / 100</div>
</div>
<div class="panel log" id="logBox">
<p>[系统] 欢迎来到铁轮工会。点击屏幕移动。</p>
</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
let cw, ch;
// 适配手机屏幕
function resize() {
cw = window.innerWidth;
ch = window.innerHeight;
canvas.width = cw;
canvas.height = ch;
}
window.addEventListener('resize', resize);
resize();
// 游戏状态数据
let state = {
role: "守法老公民",
status: "和平",
energy: 100,
log: []
};
// 玩家(蓝圈)
let player = { x: cw/2, y: ch/2, radius: 15, speed: 3, targetX: cw/2, targetY: ch/2 };
// 地图实体(简单的几何体)
let entities = [
{ type: 'prey', x: 100, y: 150, size: 15, color: '#8B4513', label: '猎物' },
{ type: 'prey', x: cw-100, y: 200, size: 15, color: '#8B4513', label: '猎物' },
{ type: 'guard', x: cw/2, y: ch-200, size: 15, color: '#e74c3c', label: '防卫队' },
{ type: 'poacher', x: 150, y: ch-150, size: 18, color: '#9b59b6', label: '越轨者' }
];
// 日志输出
function addLog(msg) {
const time = new Date().toLocaleTimeString('zh-CN', {hour: '2-digit', minute:'2-digit'});
state.log.push(`[${time}] ${msg}`);
if (state.log.length > 5) state.log.shift();
document.getElementById('logBox').innerHTML = state.log.map(m => `<p>${m}</p>`).join('');
}
// 点击屏幕移动
canvas.addEventListener('touchstart', (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
const touch = e.touches[0];
if (touch) {
player.targetX = touch.clientX - rect.left;
player.targetY = touch.clientY - rect.top;
}
});
canvas.addEventListener('mousedown', (e) => {
player.targetX = e.clientX;
player.targetY = e.clientY;
});
// 简单的碰撞检测
function checkCollision() {
entities.forEach(ent => {
const dist = Math.hypot(player.x - ent.x, player.y - ent.y);
if (dist < player.radius + ent.size) {
if (ent.type === 'prey') {
state.energy = Math.min(100, state.energy + 10);
addLog(`你捕获了猎物。行动力恢复。`);
ent.x = Math.random() * (cw - 100) + 50; // 刷新位置
ent.y = Math.random() * (ch - 200) + 100;
} else if (ent.type === 'guard') {
if (state.role === '守法老公民') {
addLog(`防卫队: 朋友,领地安全,继续巡逻吧。`);
} else {
addLog(`防卫队: 警告!你已被通缉!准备战斗或逃跑!`);
state.status = "被追捕";
state.energy -= 20; // 被攻击掉血
}
// 推开玩家防止卡住
const angle = Math.atan2(player.y - ent.y, player.x - ent.x);
player.targetX = player.x + Math.cos(angle) * 50;
player.targetY = player.y + Math.sin(angle) * 50;
} else if (ent.type === 'poacher') {
addLog(`你遇到了越轨者!【超雄模式】触发!`);
state.role = "超雄玩家 (荒野大镖客)";
state.status = "战斗";
state.energy -= 10;
ent.x = Math.random() * (cw - 100) + 50; // 怪物逃跑
ent.y = Math.random() * (ch - 200) + 100;
}
}
});
// 边界限制
player.x = Math.max(player.radius, Math.min(cw - player.radius, player.x));
player.y = Math.max(player.radius, Math.min(ch - player.radius, player.y));
}
// 游戏主循环
function update() {
// 朝目标点移动
const dx = player.targetX - player.x;
const dy = player.targetY - player.y;
const distance = Math.hypot(dx, dy);
if (distance > 5) {
player.x += (dx / distance) * player.speed;
player.y += (dy / distance) * player.speed;
} else if (state.status === '战斗') {
state.status = '和平';
addLog(`战斗结束,你收起了爪子。`);
}
// 每帧消耗行动力(模拟生存压力)
if (state.energy > 0 && distance > 5) {
state.energy -= 0.05;
}
// 检查碰撞
if (distance > 5) checkCollision();
// 更新UI
document.getElementById('role').textContent = state.role;
document.getElementById('status').textContent = state.status;
document.getElementById('energy').textContent = Math.floor(state.energy);
// 绘制
ctx.clearRect(0, 0, cw, ch);
// 画草地背景
ctx.fillStyle = '#2ecc71';
ctx.fillRect(0, 0, cw, ch);
// 画实体
entities.forEach(ent => {
ctx.beginPath();
if (ent.type === 'prey') {
ctx.rect(ent.x - ent.size/2, ent.y - ent.size/2, ent.size, ent.size);
ctx.fillStyle = ent.color;
} else if (ent.type === 'guard') {
ctx.moveTo(ent.x, ent.y - ent.size);
ctx.lineTo(ent.x + ent.size, ent.y + ent.size);
ctx.lineTo(ent.x - ent.size, ent.y + ent.size);
ctx.fillStyle = ent.color;
} else {
ctx.arc(ent.x, ent.y, ent.size, 0, Math.PI * 2);
ctx.fillStyle = ent.color;
}
ctx.fill();
});
// 画玩家(蓝圈)
ctx.beginPath();
ctx.arc(player.x, player.y, player.radius, 0, Math.PI * 2);
ctx.fillStyle = '#3498db';
ctx.fill();
ctx.strokeStyle = '#ecf0f1';
ctx.lineWidth = 2;
ctx.stroke();
requestAnimationFrame(update);
}
update();
</script>
</body>
</html>Game Source: 铁轮工会 · 原型
Creator: EpicCoder88
Libraries: none
Complexity: complex (201 lines, 7.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-epiccoder88-muqnl4nm" to link back to the original. Then publish at arcadelab.ai/publish.