Skip to content

Commit e8a9082

Browse files
authored
Create tk.html
1 parent 0b79e92 commit e8a9082

File tree

1 file changed

+369
-0
lines changed

1 file changed

+369
-0
lines changed

game/tk.html

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
2+
<!DOCTYPE html>
3+
<html>
4+
<head>
5+
<title>坦克大战</title>
6+
<style>
7+
body {
8+
margin: 0;
9+
overflow: hidden;
10+
background-color: #222;
11+
}
12+
canvas {
13+
display: block;
14+
margin: 20px auto;
15+
background-color: #000;
16+
}
17+
.game-info {
18+
color: white;
19+
text-align: center;
20+
font-family: Arial, sans-serif;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<div class="game-info">
26+
<h1>坦克大战</h1>
27+
<p>生命: <span id="lives">3</span> | 分数: <span id="score">0</span></p>
28+
</div>
29+
<canvas id="gameCanvas" width="1000" height="1000"></canvas>
30+
31+
<script>
32+
const canvas = document.getElementById('gameCanvas');
33+
const ctx = canvas.getContext('2d');
34+
const livesDisplay = document.getElementById('lives');
35+
const scoreDisplay = document.getElementById('score');
36+
37+
// 游戏状态
38+
let lives = 3;
39+
let score = 0;
40+
let gameOver = false;
41+
42+
const player = {
43+
x: 400,
44+
y: 800,
45+
width: 40,
46+
height: 40,
47+
speed: 5,
48+
direction: 0, // 0:上, 1:右, 2:下, 3:左
49+
color: '#3498db',
50+
bullets: [],
51+
cooldown: 0
52+
};
53+
54+
// 敌人坦克
55+
let enemies = [];
56+
let enemySpawnTimer = 0;
57+
58+
// 子弹
59+
class Bullet {
60+
constructor(x, y, direction, isPlayer) {
61+
this.x = x;
62+
this.y = y;
63+
this.speed = 7;
64+
this.direction = direction;
65+
this.isPlayer = isPlayer;
66+
this.width = 8;
67+
this.height = 8;
68+
}
69+
70+
update() {
71+
switch(this.direction) {
72+
case 0: this.y -= this.speed; break;
73+
case 1: this.x += this.speed; break;
74+
case 2: this.y += this.speed; break;
75+
case 3: this.x -= this.speed; break;
76+
}
77+
}
78+
79+
draw() {
80+
ctx.fillStyle = this.isPlayer ? '#2ecc71' : '#e74c3c';
81+
ctx.fillRect(this.x, this.y, this.width, this.height);
82+
}
83+
}
84+
85+
// 障碍物
86+
const walls = [];
87+
for (let i = 0; i < 10; i++) {
88+
walls.push({
89+
x: Math.random() * 560,
90+
y: Math.random() * 560,
91+
width: 40,
92+
height: 40
93+
});
94+
}
95+
96+
// 键盘控制
97+
const keys = {
98+
ArrowUp: false,
99+
ArrowRight: false,
100+
ArrowDown: false,
101+
ArrowLeft: false,
102+
Space: false
103+
};
104+
105+
window.addEventListener('keydown', (e) => {
106+
if (e.code in keys) keys[e.code] = true;
107+
});
108+
109+
window.addEventListener('keyup', (e) => {
110+
if (e.code in keys) keys[e.code] = false;
111+
});
112+
113+
// 游戏主循环
114+
function gameLoop() {
115+
if (gameOver) return;
116+
117+
update();
118+
draw();
119+
requestAnimationFrame(gameLoop);
120+
}
121+
122+
function update() {
123+
// 玩家移动
124+
if (keys.ArrowUp) {
125+
player.direction = 0;
126+
player.y = Math.max(0, player.y - player.speed);
127+
}
128+
if (keys.ArrowRight) {
129+
player.direction = 1;
130+
player.x = Math.min(canvas.width - player.width, player.x + player.speed);
131+
}
132+
if (keys.ArrowDown) {
133+
player.direction = 2;
134+
player.y = Math.min(canvas.height - player.height, player.y + player.speed);
135+
}
136+
if (keys.ArrowLeft) {
137+
player.direction = 3;
138+
player.x = Math.max(0, player.x - player.speed);
139+
}
140+
141+
// 玩家射击
142+
if (keys.Space && player.cooldown <= 0) {
143+
let bulletX, bulletY;
144+
switch(player.direction) {
145+
case 0:
146+
bulletX = player.x + player.width/2 - 4;
147+
bulletY = player.y - 8;
148+
break;
149+
case 1:
150+
bulletX = player.x + player.width;
151+
bulletY = player.y + player.height/2 - 4;
152+
break;
153+
case 2:
154+
bulletX = player.x + player.width/2 - 4;
155+
bulletY = player.y + player.height;
156+
break;
157+
case 3:
158+
bulletX = player.x - 8;
159+
bulletY = player.y + player.height/2 - 4;
160+
break;
161+
}
162+
player.bullets.push(new Bullet(bulletX, bulletY, player.direction, true));
163+
player.cooldown = 20;
164+
}
165+
if (player.cooldown > 0) player.cooldown--;
166+
167+
// 更新子弹
168+
player.bullets.forEach((bullet, index) => {
169+
bullet.update();
170+
171+
// 检查子弹是否超出边界
172+
if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
173+
player.bullets.splice(index, 1);
174+
return;
175+
}
176+
177+
// 检查子弹与墙壁碰撞
178+
for (let wall of walls) {
179+
if (checkCollision(bullet, wall)) {
180+
player.bullets.splice(index, 1);
181+
return;
182+
}
183+
}
184+
185+
// 检查玩家子弹与敌人碰撞
186+
if (bullet.isPlayer) {
187+
enemies.forEach((enemy, enemyIndex) => {
188+
if (checkCollision(bullet, enemy)) {
189+
player.bullets.splice(index, 1);
190+
enemies.splice(enemyIndex, 1);
191+
score += 100;
192+
scoreDisplay.textContent = score;
193+
return;
194+
}
195+
});
196+
}
197+
});
198+
199+
// 生成敌人
200+
enemySpawnTimer++;
201+
if (enemySpawnTimer > 120 && enemies.length < 5) {
202+
spawnEnemy();
203+
enemySpawnTimer = 0;
204+
}
205+
206+
// 更新敌人
207+
enemies.forEach((enemy, index) => {
208+
if (Math.random() < 0.03) {
209+
enemy.direction = Math.floor(Math.random() * 3);
210+
}//
211+
//if (Math.random() < 0.02) {
212+
// enemy.direction = Math.floor(Math.random() * 4);
213+
// }
214+
215+
switch(enemy.direction) {
216+
case 0: enemy.y = Math.max(0, enemy.y - enemy.speed); break;
217+
case 1: enemy.x = Math.min(canvas.width - enemy.width, enemy.x + enemy.speed); break;
218+
case 2: enemy.y = Math.min(canvas.height - enemy.height, enemy.y + enemy.speed); break;
219+
case 3: enemy.x = Math.max(0, enemy.x - enemy.speed); break;
220+
}
221+
222+
// 敌人射击
223+
if (Math.random() < 0.01 && enemy.cooldown <= 0) {
224+
let bulletX, bulletY;
225+
switch(enemy.direction) {
226+
case 0:
227+
bulletX = enemy.x + enemy.width/2 - 4;
228+
bulletY = enemy.y - 8;
229+
break;
230+
case 1:
231+
bulletX = enemy.x + enemy.width;
232+
bulletY = enemy.y + enemy.height/2 - 4;
233+
break;
234+
case 2:
235+
bulletX = enemy.x + enemy.width/2 - 4;
236+
bulletY = enemy.y + enemy.height;
237+
break;
238+
case 3:
239+
bulletX = enemy.x - 8;
240+
bulletY = enemy.y + enemy.height/2 - 4;
241+
break;
242+
}
243+
enemy.bullets.push(new Bullet(bulletX, bulletY, enemy.direction, false));
244+
enemy.cooldown = 60;
245+
}
246+
if (enemy.cooldown > 0) enemy.cooldown--;
247+
248+
// 敌人子弹
249+
enemy.bullets.forEach((bullet, bulletIndex) => {
250+
bullet.update();
251+
252+
// 检查子弹是否超出边界
253+
if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
254+
enemy.bullets.splice(bulletIndex, 1);
255+
return;
256+
}
257+
258+
// 检查子弹与墙壁碰撞
259+
for (let wall of walls) {
260+
if (checkCollision(bullet, wall)) {
261+
enemy.bullets.splice(bulletIndex, 1);
262+
return;
263+
}
264+
}
265+
266+
// 检查敌人子弹与玩家碰撞
267+
if (!bullet.isPlayer && checkCollision(bullet, player)) {
268+
enemy.bullets.splice(bulletIndex, 1);
269+
lives--;
270+
livesDisplay.textContent = lives;
271+
if (lives <= 0) {
272+
gameOver = true;
273+
alert('游戏结束!你的分数: ' + score);
274+
}
275+
return;
276+
}
277+
});
278+
});
279+
}
280+
281+
function draw() {
282+
// 清空画布
283+
ctx.clearRect(0, 0, canvas.width, canvas.height);
284+
285+
// 绘制墙壁
286+
ctx.fillStyle = '#7f8c8d';
287+
walls.forEach(wall => {
288+
ctx.fillRect(wall.x, wall.y, wall.width, wall.height);
289+
});
290+
291+
// 绘制玩家坦克
292+
ctx.fillStyle = player.color;
293+
ctx.fillRect(player.x, player.y, player.width, player.height);
294+
295+
// 绘制炮管
296+
ctx.fillStyle = '#2980b9';
297+
switch(player.direction) {
298+
case 0:
299+
ctx.fillRect(player.x + player.width/2 - 5, player.y - 10, 10, 15);
300+
break;
301+
case 1:
302+
ctx.fillRect(player.x + player.width, player.y + player.height/2 - 5, 15, 10);
303+
break;
304+
case 2:
305+
ctx.fillRect(player.x + player.width/2 - 5, player.y + player.height, 10, 15);
306+
break;
307+
case 3:
308+
ctx.fillRect(player.x - 15, player.y + player.height/2 - 5, 15, 10);
309+
break;
310+
}
311+
312+
// 绘制子弹
313+
player.bullets.forEach(bullet => bullet.draw());
314+
315+
// 绘制敌人
316+
enemies.forEach(enemy => {
317+
ctx.fillStyle = enemy.color;
318+
ctx.fillRect(enemy.x, enemy.y, enemy.width, enemy.height);
319+
320+
// 绘制炮管
321+
ctx.fillStyle = '#c0392b';
322+
switch(enemy.direction) {
323+
case 0:
324+
ctx.fillRect(enemy.x + enemy.width/2 - 5, enemy.y - 10, 10, 15);
325+
break;
326+
case 1:
327+
ctx.fillRect(enemy.x + enemy.width, enemy.y + enemy.height/2 - 5, 15, 10);
328+
break;
329+
case 2:
330+
ctx.fillRect(enemy.x + enemy.width/2 - 5, enemy.y + enemy.height, 10, 15);
331+
break;
332+
case 3:
333+
ctx.fillRect(enemy.x - 15, enemy.y + enemy.height/2 - 5, 15, 10);
334+
break;
335+
}
336+
337+
enemy.bullets.forEach(bullet => bullet.draw());
338+
});
339+
}
340+
341+
function spawnEnemy() {
342+
const x = Math.random() * (canvas.width - 40);
343+
const y = Math.random() * 200;
344+
345+
enemies.push({
346+
x: x,
347+
y: y,
348+
width: 40,
349+
height: 40,
350+
speed: 2,
351+
direction: 2,
352+
color: '#e74c3c',
353+
bullets: [],
354+
cooldown: 0
355+
});
356+
}
357+
358+
function checkCollision(obj1, obj2) {
359+
return obj1.x < obj2.x + obj2.width &&
360+
obj1.x + obj1.width > obj2.x &&
361+
obj1.y < obj2.y + obj2.height &&
362+
obj1.y + obj1.height > obj2.y;
363+
}
364+
365+
// 开始游戏
366+
gameLoop();
367+
</script>
368+
</body>
369+
</html>

0 commit comments

Comments
 (0)