Skip to content

Commit 305deec

Browse files
authored
Create gun_game.html
1 parent 384c2f0 commit 305deec

File tree

1 file changed

+303
-0
lines changed

1 file changed

+303
-0
lines changed

game/gun_game.html

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
1+
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<title>枪战</title>
6+
<style>
7+
body { margin: 0; overflow: hidden; background: #222; }
8+
canvas { display: block; }
9+
#hud {
10+
position: absolute;
11+
top: 10px;
12+
left: 10px;
13+
color: white;
14+
font-family: Arial;
15+
font-size: 16px;
16+
}
17+
#ammo {
18+
position: absolute;
19+
bottom: 10px;
20+
right: 10px;
21+
color: white;
22+
font-family: Arial;
23+
font-size: 24px;
24+
}
25+
#safe-zone {
26+
position: absolute;
27+
left: 10px;
28+
bottom: 10px;
29+
width: 150px;
30+
height: 150px;
31+
border: 2px dashed rgba(0, 255, 0, 0.5);
32+
pointer-events: none;
33+
}
34+
</style>
35+
</head>
36+
<body>
37+
<div id="hud">生命: 100 | 击杀: 0</div>
38+
<div id="ammo">弹药: ∞</div>
39+
<div id="safe-zone"></div>
40+
<canvas id="gameCanvas"></canvas>
41+
<script>
42+
// 游戏初始化
43+
const canvas = document.getElementById('gameCanvas');
44+
const ctx = canvas.getContext('2d');
45+
canvas.width = window.innerWidth;
46+
canvas.height = window.innerHeight;
47+
48+
// 安全区定义
49+
const safeZone = {
50+
x: 10,
51+
y: canvas.height - 160,
52+
width: 150,
53+
height: 150,
54+
active: false
55+
};
56+
57+
// 游戏状态
58+
const game = {
59+
player: {
60+
x: canvas.width/2,
61+
y: canvas.height/2,
62+
size: 30,
63+
speed: 5,
64+
health: 100,
65+
color: '#3498db'
66+
},
67+
bullets: [],
68+
enemies: [],
69+
kills: 0,
70+
keys: {},
71+
lastShot: 0,
72+
rapidFire: false,
73+
rapidFireInterval: null
74+
};
75+
76+
// 敌人生成
77+
function spawnEnemy() {
78+
const side = Math.floor(Math.random() * 4);
79+
let x, y;
80+
81+
switch(side) {
82+
case 0: x = 0; y = Math.random() * canvas.height; break;
83+
case 1: x = canvas.width; y = Math.random() * canvas.height; break;
84+
case 2: x = Math.random() * canvas.width; y = 0; break;
85+
case 3: x = Math.random() * canvas.width; y = canvas.height; break;
86+
}
87+
88+
// 确保敌人不会在安全区生成
89+
if (x > safeZone.x && x < safeZone.x + safeZone.width &&
90+
y > safeZone.y && y < safeZone.y + safeZone.height) {
91+
return spawnEnemy(); // 重新生成
92+
}
93+
94+
game.enemies.push({
95+
x: x,
96+
y: y,
97+
size: 25,
98+
speed: 1 + Math.random() * 2,
99+
color: `hsl(${Math.random()*360}, 70%, 50%)`
100+
});
101+
}
102+
103+
// 射击函数
104+
function shoot() {
105+
const now = Date.now();
106+
if (now - game.lastShot < 100 && !game.rapidFire) return;
107+
108+
game.lastShot = now;
109+
110+
// 计算子弹方向(朝向鼠标)
111+
const angle = Math.atan2(
112+
mouseY - game.player.y,
113+
mouseX - game.player.x
114+
);
115+
116+
game.bullets.push({
117+
x: game.player.x,
118+
y: game.player.y,
119+
dx: Math.cos(angle) * 10,
120+
dy: Math.sin(angle) * 10,
121+
size: 5,
122+
color: '#f1c40f'
123+
});
124+
}
125+
126+
// 连发模式切换
127+
function toggleRapidFire() {
128+
game.rapidFire = !game.rapidFire;
129+
if (game.rapidFire) {
130+
game.rapidFireInterval = setInterval(shoot, 100);
131+
document.getElementById('ammo').textContent = "弹药: ∞";
132+
} else {
133+
clearInterval(game.rapidFireInterval);
134+
document.getElementById('ammo').textContent = "弹药: 30";
135+
}
136+
}
137+
138+
// 更新游戏状态
139+
function update() {
140+
// 玩家移动
141+
if (game.keys['w'] || game.keys['ArrowUp']) game.player.y -= game.player.speed;
142+
if (game.keys['s'] || game.keys['ArrowDown']) game.player.y += game.player.speed;
143+
if (game.keys['a'] || game.keys['ArrowLeft']) game.player.x -= game.player.speed;
144+
if (game.keys['d'] || game.keys['ArrowRight']) game.player.x += game.player.speed;
145+
146+
// 边界检查
147+
game.player.x = Math.max(game.player.size, Math.min(canvas.width-game.player.size, game.player.x));
148+
game.player.y = Math.max(game.player.size, Math.min(canvas.height-game.player.size, game.player.y));
149+
150+
// 检查是否在安全区
151+
safeZone.active = (
152+
game.player.x > safeZone.x &&
153+
game.player.x < safeZone.x + safeZone.width &&
154+
game.player.y > safeZone.y &&
155+
game.player.y < safeZone.y + safeZone.height
156+
);
157+
158+
// 移动子弹
159+
game.bullets.forEach((bullet, i) => {
160+
bullet.x += bullet.dx;
161+
bullet.y += bullet.dy;
162+
163+
// 移除超出屏幕的子弹
164+
if (bullet.x < 0 || bullet.x > canvas.width ||
165+
bullet.y < 0 || bullet.y > canvas.height) {
166+
game.bullets.splice(i, 1);
167+
}
168+
});
169+
170+
// 移动敌人(不会进入安全区)
171+
game.enemies.forEach((enemy, i) => {
172+
let dx = game.player.x - enemy.x;
173+
let dy = game.player.y - enemy.y;
174+
175+
// 如果玩家在安全区,敌人停止追击
176+
if (!safeZone.active) {
177+
const dist = Math.sqrt(dx*dx + dy*dy);
178+
enemy.x += (dx/dist) * enemy.speed;
179+
enemy.y += (dy/dist) * enemy.speed;
180+
}
181+
182+
// 检测敌人与玩家碰撞
183+
if (Math.sqrt(
184+
Math.pow(game.player.x - enemy.x, 2) +
185+
Math.pow(game.player.y - enemy.y, 2)
186+
) < game.player.size + enemy.size) {
187+
if (!safeZone.active) {
188+
game.player.health -= 0.5;
189+
document.getElementById('hud').textContent =
190+
`生命: ${Math.floor(game.player.health)} | 击杀: ${game.kills}`;
191+
}
192+
}
193+
194+
// 检测子弹与敌人碰撞
195+
game.bullets.forEach((bullet, bi) => {
196+
if (Math.sqrt(
197+
Math.pow(bullet.x - enemy.x, 2) +
198+
Math.pow(bullet.y - enemy.y, 2)
199+
) < enemy.size) {
200+
game.enemies.splice(i, 1);
201+
game.bullets.splice(bi, 1);
202+
game.kills++;
203+
document.getElementById('hud').textContent =
204+
`生命: ${Math.floor(game.player.health)} | 击杀: ${game.kills}`;
205+
}
206+
});
207+
});
208+
209+
// 随机生成敌人
210+
if (Math.random() < 0.02) spawnEnemy();
211+
}
212+
213+
// 渲染游戏
214+
function render() {
215+
ctx.clearRect(0, 0, canvas.width, canvas.height);
216+
217+
// 绘制安全区
218+
ctx.strokeStyle = safeZone.active ? 'rgba(0, 255, 0, 0.7)' : 'rgba(0, 255, 0, 0.3)';
219+
ctx.lineWidth = 2;
220+
ctx.strokeRect(safeZone.x, safeZone.y, safeZone.width, safeZone.height);
221+
ctx.fillStyle = 'rgba(0, 255, 0, 0.1)';
222+
ctx.fillRect(safeZone.x, safeZone.y, safeZone.width, safeZone.height);
223+
224+
// 绘制玩家
225+
ctx.fillStyle = game.player.color;
226+
ctx.beginPath();
227+
ctx.arc(game.player.x, game.player.y, game.player.size, 0, Math.PI*2);
228+
ctx.fill();
229+
230+
// 绘制枪管(指向鼠标)
231+
const angle = Math.atan2(mouseY - game.player.y, mouseX - game.player.x);
232+
ctx.strokeStyle = '#2c3e50';
233+
ctx.lineWidth = 5;
234+
ctx.beginPath();
235+
ctx.moveTo(game.player.x, game.player.y);
236+
ctx.lineTo(
237+
game.player.x + Math.cos(angle) * game.player.size,
238+
game.player.y + Math.sin(angle) * game.player.size
239+
);
240+
ctx.stroke();
241+
242+
// 绘制子弹
243+
game.bullets.forEach(bullet => {
244+
ctx.fillStyle = bullet.color;
245+
ctx.beginPath();
246+
ctx.arc(bullet.x, bullet.y, bullet.size, 0, Math.PI*2);
247+
ctx.fill();
248+
});
249+
250+
// 绘制敌人
251+
game.enemies.forEach(enemy => {
252+
ctx.fillStyle = enemy.color;
253+
ctx.beginPath();
254+
ctx.arc(enemy.x, enemy.y, enemy.size, 0, Math.PI*2);
255+
ctx.fill();
256+
});
257+
}
258+
259+
// 游戏循环
260+
function gameLoop() {
261+
update();
262+
render();
263+
requestAnimationFrame(gameLoop);
264+
}
265+
266+
// 鼠标位置跟踪
267+
let mouseX = 0, mouseY = 0;
268+
window.addEventListener('mousemove', (e) => {
269+
mouseX = e.clientX;
270+
mouseY = e.clientY;
271+
});
272+
273+
// 键盘控制
274+
window.addEventListener('keydown', (e) => {
275+
game.keys[e.key.toLowerCase()] = true;
276+
277+
// G键切换连发模式
278+
if (e.key === 'g') {
279+
toggleRapidFire();
280+
}
281+
282+
// 空格键射击(单发)
283+
if (e.key === ' ' && !game.rapidFire) {
284+
shoot();
285+
}
286+
});
287+
288+
window.addEventListener('keyup', (e) => {
289+
game.keys[e.key.toLowerCase()] = false;
290+
});
291+
292+
window.addEventListener('resize', () => {
293+
canvas.width = window.innerWidth;
294+
canvas.height = window.innerHeight;
295+
safeZone.y = canvas.height - 160;
296+
});
297+
298+
// 启动游戏
299+
for (let i = 0; i < 3; i++) spawnEnemy();
300+
gameLoop();
301+
</script>
302+
</body>
303+
</html>

0 commit comments

Comments
 (0)