awacke1 commited on
Commit
7790c5f
·
verified ·
1 Parent(s): e743d91

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +306 -19
index.html CHANGED
@@ -1,19 +1,306 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Tank Game</title>
7
+ <style>
8
+ body { margin: 0; overflow: hidden; font-family: Arial, sans-serif; }
9
+ #gameArea { width: 100vw; height: 100vh; background-color: #f0f0f0; }
10
+ #score { position: absolute; top: 10px; left: 10px; font-size: 24px; font-weight: bold; }
11
+ #level { position: absolute; top: 10px; right: 10px; font-size: 24px; font-weight: bold; }
12
+ #nextLevel { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 48px; font-weight: bold; display: none; }
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <div id="score">Score: 0</div>
17
+ <div id="level">Level: 1</div>
18
+ <div id="nextLevel">Next Level</div>
19
+ <svg id="gameArea"></svg>
20
+ <script>
21
+ const svg = document.getElementById('gameArea');
22
+ const scoreElement = document.getElementById('score');
23
+ const levelElement = document.getElementById('level');
24
+ const nextLevelElement = document.getElementById('nextLevel');
25
+ const svgNS = "http://www.w3.org/2000/svg";
26
+
27
+ const GAME_WIDTH = window.innerWidth;
28
+ const GAME_HEIGHT = window.innerHeight;
29
+ const TANK_SIZE = 30;
30
+ const BULLET_SIZE = 5;
31
+ const TANK_SPEED = 2;
32
+ const AI_TANK_SPEED = 1.5;
33
+ const BULLET_SPEED = 5;
34
+ const MAX_HIT_POINTS = 20;
35
+ const MAX_TANKS = 5;
36
+ const MAX_TANKS_ON_SCREEN = 50;
37
+ const SPAWN_DELAY = 5000; // 5 seconds in milliseconds
38
+
39
+ let score = 0;
40
+ let level = 1;
41
+ let spawnQueue = [];
42
+ let lastSpawnTime = 0;
43
+
44
+ class Tank {
45
+ constructor(x, y, color, isPlayer = false) {
46
+ this.x = x;
47
+ this.y = y;
48
+ this.angle = 0;
49
+ this.color = color;
50
+ this.isPlayer = isPlayer;
51
+ this.hitPoints = MAX_HIT_POINTS;
52
+ this.element = document.createElementNS(svgNS, "g");
53
+ this.tankBody = document.createElementNS(svgNS, "polygon");
54
+ this.shield = document.createElementNS(svgNS, "circle");
55
+ this.hitPointsText = document.createElementNS(svgNS, "text");
56
+
57
+ this.tankBody.setAttribute("fill", color);
58
+ this.shield.setAttribute("fill", "none");
59
+ this.shield.setAttribute("stroke", color);
60
+ this.shield.setAttribute("stroke-width", this.hitPoints);
61
+ this.shield.setAttribute("r", TANK_SIZE + 10);
62
+
63
+ this.hitPointsText.setAttribute("text-anchor", "middle");
64
+ this.hitPointsText.setAttribute("fill", "black");
65
+ this.hitPointsText.setAttribute("font-size", "12px");
66
+
67
+ this.element.appendChild(this.shield);
68
+ this.element.appendChild(this.tankBody);
69
+ this.element.appendChild(this.hitPointsText);
70
+ svg.appendChild(this.element);
71
+
72
+ this.velocity = { x: 0, y: 0 };
73
+ this.isAlive = true;
74
+ }
75
+
76
+ update(playerX, playerY) {
77
+ if (!this.isAlive) return;
78
+
79
+ if (!this.isPlayer) {
80
+ const dx = playerX - this.x;
81
+ const dy = playerY - this.y;
82
+ this.angle = Math.atan2(dy, dx);
83
+ this.x += Math.cos(this.angle) * AI_TANK_SPEED;
84
+ this.y += Math.sin(this.angle) * AI_TANK_SPEED;
85
+ } else {
86
+ this.x += this.velocity.x;
87
+ this.y += this.velocity.y;
88
+ }
89
+
90
+ // Bounce off walls
91
+ if (this.x < TANK_SIZE || this.x > GAME_WIDTH - TANK_SIZE) {
92
+ this.velocity.x *= -1;
93
+ this.x = Math.max(TANK_SIZE, Math.min(GAME_WIDTH - TANK_SIZE, this.x));
94
+ }
95
+ if (this.y < TANK_SIZE || this.y > GAME_HEIGHT - TANK_SIZE) {
96
+ this.velocity.y *= -1;
97
+ this.y = Math.max(TANK_SIZE, Math.min(GAME_HEIGHT - TANK_SIZE, this.y));
98
+ }
99
+
100
+ const points = [
101
+ [TANK_SIZE, 0],
102
+ [-TANK_SIZE / 2, -TANK_SIZE / 2],
103
+ [-TANK_SIZE / 2, TANK_SIZE / 2]
104
+ ].map(([x, y]) => {
105
+ const rotatedX = x * Math.cos(this.angle) - y * Math.sin(this.angle);
106
+ const rotatedY = x * Math.sin(this.angle) + y * Math.cos(this.angle);
107
+ return `${rotatedX},${rotatedY}`;
108
+ }).join(" ");
109
+
110
+ this.tankBody.setAttribute("points", points);
111
+ this.shield.setAttribute("cx", 0);
112
+ this.shield.setAttribute("cy", 0);
113
+ this.shield.setAttribute("stroke-width", this.hitPoints);
114
+ this.hitPointsText.textContent = this.hitPoints;
115
+ this.hitPointsText.setAttribute("x", 0);
116
+ this.hitPointsText.setAttribute("y", -TANK_SIZE - 5);
117
+
118
+ this.element.setAttribute("transform", `translate(${this.x},${this.y}) rotate(${this.angle * 180 / Math.PI})`);
119
+ }
120
+
121
+ shoot() {
122
+ return new Bullet(this.x + Math.cos(this.angle) * TANK_SIZE,
123
+ this.y + Math.sin(this.angle) * TANK_SIZE,
124
+ this.angle,
125
+ this.color,
126
+ this.isPlayer);
127
+ }
128
+
129
+ takeDamage(damage) {
130
+ this.hitPoints -= damage;
131
+ if (this.hitPoints <= 0) {
132
+ this.explode();
133
+ }
134
+ }
135
+
136
+ explode() {
137
+ if (!this.isAlive) return;
138
+ this.isAlive = false;
139
+ this.element.remove();
140
+ updateScore(1);
141
+ }
142
+ }
143
+
144
+ class Bullet {
145
+ constructor(x, y, angle, color, isPlayerBullet) {
146
+ this.x = x;
147
+ this.y = y;
148
+ this.angle = angle;
149
+ this.color = color;
150
+ this.isPlayerBullet = isPlayerBullet;
151
+ this.element = document.createElementNS(svgNS, "circle");
152
+ this.element.setAttribute("r", BULLET_SIZE);
153
+ this.element.setAttribute("fill", color);
154
+ svg.appendChild(this.element);
155
+ }
156
+
157
+ update() {
158
+ this.x += Math.cos(this.angle) * BULLET_SPEED;
159
+ this.y += Math.sin(this.angle) * BULLET_SPEED;
160
+ this.element.setAttribute("cx", this.x);
161
+ this.element.setAttribute("cy", this.y);
162
+
163
+ return this.x > 0 && this.x < GAME_WIDTH && this.y > 0 && this.y < GAME_HEIGHT;
164
+ }
165
+
166
+ remove() {
167
+ this.element.remove();
168
+ }
169
+ }
170
+
171
+ const player = new Tank(GAME_WIDTH / 2, GAME_HEIGHT / 2, "blue", true);
172
+ let aiTanks = [];
173
+
174
+ function queueEnemySpawn() {
175
+ const tanksToSpawn = MAX_TANKS - aiTanks.length;
176
+ for (let i = 0; i < tanksToSpawn; i++) {
177
+ spawnQueue.push({
178
+ x: Math.random() * (GAME_WIDTH - 2 * TANK_SIZE) + TANK_SIZE,
179
+ y: Math.random() * (GAME_HEIGHT - 2 * TANK_SIZE) + TANK_SIZE,
180
+ color: `hsl(${Math.random() * 360}, 100%, 50%)`
181
+ });
182
+ }
183
+ }
184
+
185
+ function spawnEnemies() {
186
+ const currentTime = Date.now();
187
+ if (currentTime - lastSpawnTime > SPAWN_DELAY && spawnQueue.length > 0 && aiTanks.length < MAX_TANKS_ON_SCREEN) {
188
+ const spawnData = spawnQueue.shift();
189
+ let canSpawn = true;
190
+
191
+ // Check if the spawn location is clear
192
+ for (let tank of aiTanks) {
193
+ if (distance(tank, spawnData) < 3 * TANK_SIZE) {
194
+ canSpawn = false;
195
+ break;
196
+ }
197
+ }
198
+
199
+ if (canSpawn) {
200
+ aiTanks.push(new Tank(spawnData.x, spawnData.y, spawnData.color));
201
+ lastSpawnTime = currentTime;
202
+ } else {
203
+ // If can't spawn, put back in queue
204
+ spawnQueue.push(spawnData);
205
+ }
206
+ }
207
+ }
208
+
209
+ let bullets = [];
210
+ let keys = {};
211
+
212
+ document.addEventListener('keydown', (event) => {
213
+ keys[event.key.toLowerCase()] = true;
214
+ });
215
+
216
+ document.addEventListener('keyup', (event) => {
217
+ keys[event.key.toLowerCase()] = false;
218
+ });
219
+
220
+ svg.addEventListener('mousemove', (event) => {
221
+ const rect = svg.getBoundingClientRect();
222
+ const mouseX = event.clientX - rect.left;
223
+ const mouseY = event.clientY - rect.top;
224
+ player.angle = Math.atan2(mouseY - player.y, mouseX - player.x);
225
+ });
226
+
227
+ svg.addEventListener('click', () => {
228
+ bullets.push(player.shoot());
229
+ });
230
+
231
+ function updatePlayerPosition() {
232
+ let dx = 0, dy = 0;
233
+ if (keys['w']) dy -= TANK_SPEED;
234
+ if (keys['s']) dy += TANK_SPEED;
235
+ if (keys['a']) dx -= TANK_SPEED;
236
+ if (keys['d']) dx += TANK_SPEED;
237
+
238
+ // Normalize diagonal movement
239
+ if (dx !== 0 && dy !== 0) {
240
+ dx /= Math.sqrt(2);
241
+ dy /= Math.sqrt(2);
242
+ }
243
+
244
+ player.velocity = { x: dx, y: dy };
245
+ }
246
+
247
+ function checkCollisions() {
248
+ bullets.forEach((bullet, bulletIndex) => {
249
+ if (bullet.isPlayerBullet) {
250
+ aiTanks.forEach((tank, tankIndex) => {
251
+ if (tank.isAlive && distance(bullet, tank) < TANK_SIZE) {
252
+ bullet.remove();
253
+ bullets.splice(bulletIndex, 1);
254
+ tank.takeDamage(1);
255
+ }
256
+ });
257
+ }
258
+ });
259
+ }
260
+
261
+ function distance(obj1, obj2) {
262
+ return Math.sqrt((obj1.x - obj2.x)**2 + (obj1.y - obj2.y)**2);
263
+ }
264
+
265
+ function updateScore(points) {
266
+ score += points;
267
+ scoreElement.textContent = `Score: ${score}`;
268
+ }
269
+
270
+ function updateLevel() {
271
+ level++;
272
+ levelElement.textContent = `Level: ${level}`;
273
+ nextLevelElement.style.display = 'block';
274
+ setTimeout(() => {
275
+ nextLevelElement.style.display = 'none';
276
+ queueEnemySpawn();
277
+ }, 2000);
278
+ }
279
+
280
+ function gameLoop() {
281
+ updatePlayerPosition();
282
+ player.update();
283
+ aiTanks = aiTanks.filter(tank => tank.isAlive);
284
+ aiTanks.forEach(tank => {
285
+ tank.update(player.x, player.y);
286
+ if (Math.random() < 0.02) {
287
+ bullets.push(tank.shoot());
288
+ }
289
+ });
290
+
291
+ bullets = bullets.filter(bullet => bullet.update());
292
+ checkCollisions();
293
+ spawnEnemies();
294
+
295
+ if (aiTanks.length === 0 && spawnQueue.length === 0) {
296
+ updateLevel();
297
+ }
298
+
299
+ requestAnimationFrame(gameLoop);
300
+ }
301
+
302
+ queueEnemySpawn(); // Initial spawn queue
303
+ gameLoop();
304
+ </script>
305
+ </body>
306
+ </html>