ILLERRAPS commited on
Commit
adf846c
·
verified ·
1 Parent(s): 71ea537

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +6 -4
  2. index.html +1137 -19
  3. prompts.txt +0 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Weapon Pac
3
- emoji: 📉
4
- colorFrom: indigo
5
  colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: weapon-pac
3
+ emoji: 🐳
4
+ colorFrom: red
5
  colorTo: blue
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1137 @@
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>Weapon-Pac: Battle Maze</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @keyframes ghost-pulse {
11
+ 0%, 100% { opacity: 1; }
12
+ 50% { opacity: 0.5; }
13
+ }
14
+
15
+ @keyframes powerup-glow {
16
+ 0%, 100% { box-shadow: 0 0 5px 2px #ff0; }
17
+ 50% { box-shadow: 0 0 15px 5px #ff0; }
18
+ }
19
+
20
+ .ghost {
21
+ animation: ghost-pulse 2s infinite;
22
+ }
23
+
24
+ .powerup {
25
+ animation: powerup-glow 1.5s infinite;
26
+ }
27
+
28
+ .bullet {
29
+ transition: all 0.1s linear;
30
+ }
31
+
32
+ #game-container {
33
+ background-color: #111;
34
+ position: relative;
35
+ overflow: hidden;
36
+ }
37
+
38
+ .wall {
39
+ background-color: #1a3d8a;
40
+ box-shadow: inset 0 0 10px #000;
41
+ }
42
+
43
+ .path {
44
+ background-color: #000;
45
+ }
46
+
47
+ #player {
48
+ transition: transform 0.2s ease;
49
+ z-index: 10;
50
+ }
51
+
52
+ .weapon-icon {
53
+ transition: all 0.3s ease;
54
+ }
55
+
56
+ .weapon-icon:hover {
57
+ transform: scale(1.2);
58
+ filter: drop-shadow(0 0 5px #fff);
59
+ }
60
+
61
+ #game-overlay {
62
+ background-color: rgba(0, 0, 0, 0.8);
63
+ z-index: 100;
64
+ }
65
+ </style>
66
+ </head>
67
+ <body class="bg-gray-900 text-white font-mono flex flex-col items-center justify-center min-h-screen p-4">
68
+ <div class="max-w-4xl w-full">
69
+ <header class="flex justify-between items-center mb-4">
70
+ <h1 class="text-3xl font-bold text-yellow-400 flex items-center">
71
+ <i class="fas fa-ghost mr-2"></i> WEAPON-PAC
72
+ </h1>
73
+ <div class="flex items-center space-x-6">
74
+ <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
75
+ <span class="text-yellow-400 mr-2">SCORE:</span>
76
+ <span id="score" class="text-xl font-bold">0</span>
77
+ </div>
78
+ <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
79
+ <span class="text-red-400 mr-2">LIVES:</span>
80
+ <span id="lives" class="text-xl font-bold">3</span>
81
+ </div>
82
+ <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
83
+ <span class="text-blue-400 mr-2">WEAPON:</span>
84
+ <span id="current-weapon" class="text-xl font-bold">PISTOL</span>
85
+ </div>
86
+ </div>
87
+ </header>
88
+
89
+ <div class="relative">
90
+ <div id="game-container" class="w-full h-96 border-4 border-blue-800 rounded-lg relative">
91
+ <!-- Game elements will be generated by JavaScript -->
92
+ </div>
93
+
94
+ <div id="game-overlay" class="absolute inset-0 flex flex-col items-center justify-center hidden">
95
+ <div class="bg-gray-900 border-2 border-yellow-400 rounded-lg p-8 max-w-md text-center">
96
+ <h2 id="overlay-title" class="text-3xl font-bold mb-4 text-yellow-400">GAME OVER</h2>
97
+ <p id="overlay-message" class="text-xl mb-6">You scored <span id="final-score" class="text-yellow-400">0</span> points!</p>
98
+ <button id="restart-btn" class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg text-lg transition">
99
+ PLAY AGAIN
100
+ </button>
101
+ </div>
102
+ </div>
103
+ </div>
104
+
105
+ <div class="mt-6 bg-gray-800 rounded-lg p-4">
106
+ <div class="flex justify-between items-center mb-4">
107
+ <h2 class="text-xl font-bold text-yellow-400">WEAPON SELECTOR</h2>
108
+ <div class="flex items-center">
109
+ <span class="mr-2">AMMO:</span>
110
+ <span id="ammo-count" class="font-bold">∞</span>
111
+ </div>
112
+ </div>
113
+ <div class="grid grid-cols-5 gap-4">
114
+ <div class="weapon-icon bg-gray-700 p-3 rounded-lg cursor-pointer border-2 border-yellow-500 flex flex-col items-center" data-weapon="pistol">
115
+ <i class="fas fa-gun text-2xl mb-1"></i>
116
+ <span class="text-sm">PISTOL</span>
117
+ </div>
118
+ <div class="weapon-icon bg-gray-700 p-3 rounded-lg cursor-pointer border-2 border-gray-500 flex flex-col items-center" data-weapon="shotgun">
119
+ <i class="fas fa-gun text-2xl mb-1"></i>
120
+ <span class="text-sm">SHOTGUN</span>
121
+ </div>
122
+ <div class="weapon-icon bg-gray-700 p-3 rounded-lg cursor-pointer border-2 border-gray-500 flex flex-col items-center" data-weapon="laser">
123
+ <i class="fas fa-bolt text-2xl mb-1"></i>
124
+ <span class="text-sm">LASER</span>
125
+ </div>
126
+ <div class="weapon-icon bg-gray-700 p-3 rounded-lg cursor-pointer border-2 border-gray-500 flex flex-col items-center" data-weapon="rocket">
127
+ <i class="fas fa-rocket text-2xl mb-1"></i>
128
+ <span class="text-sm">ROCKET</span>
129
+ </div>
130
+ <div class="weapon-icon bg-gray-700 p-3 rounded-lg cursor-pointer border-2 border-gray-500 flex flex-col items-center" data-weapon="mine">
131
+ <i class="fas fa-land-mine-on text-2xl mb-1"></i>
132
+ <span class="text-sm">MINE</span>
133
+ </div>
134
+ </div>
135
+ </div>
136
+
137
+ <div class="mt-6 bg-gray-800 rounded-lg p-4">
138
+ <h2 class="text-xl font-bold text-yellow-400 mb-2">CONTROLS</h2>
139
+ <div class="grid grid-cols-2 gap-4">
140
+ <div>
141
+ <p class="mb-2"><span class="font-bold">WASD</span> or <span class="font-bold">Arrow Keys</span> to move</p>
142
+ <p><span class="font-bold">SPACE</span> to shoot</p>
143
+ </div>
144
+ <div>
145
+ <p class="mb-2"><span class="font-bold">1-5</span> to switch weapons</p>
146
+ <p>Click weapon icons to select</p>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ </div>
151
+
152
+ <script>
153
+ document.addEventListener('DOMContentLoaded', () => {
154
+ // Game constants
155
+ const GRID_SIZE = 19;
156
+ const CELL_SIZE = 20;
157
+ const PLAYER_SPEED = 150;
158
+ const GHOST_SPEED = 180;
159
+ const BULLET_SPEED = 8;
160
+
161
+ // Game state
162
+ let score = 0;
163
+ let lives = 3;
164
+ let gameRunning = true;
165
+ let playerDirection = 'right';
166
+ let nextDirection = 'right';
167
+ let playerPosition = { x: 1, y: 1 };
168
+ let ghosts = [];
169
+ let bullets = [];
170
+ let powerups = [];
171
+ let walls = [];
172
+ let pellets = [];
173
+ let mines = [];
174
+ let currentWeapon = 'pistol';
175
+ let ammo = {
176
+ pistol: Infinity,
177
+ shotgun: 20,
178
+ laser: 30,
179
+ rocket: 5,
180
+ mine: 3
181
+ };
182
+
183
+ // DOM elements
184
+ const gameContainer = document.getElementById('game-container');
185
+ const scoreDisplay = document.getElementById('score');
186
+ const livesDisplay = document.getElementById('lives');
187
+ const weaponDisplay = document.getElementById('current-weapon');
188
+ const ammoDisplay = document.getElementById('ammo-count');
189
+ const gameOverlay = document.getElementById('game-overlay');
190
+ const overlayTitle = document.getElementById('overlay-title');
191
+ const overlayMessage = document.getElementById('overlay-message');
192
+ const finalScore = document.getElementById('final-score');
193
+ const restartBtn = document.getElementById('restart-btn');
194
+ const weaponIcons = document.querySelectorAll('.weapon-icon');
195
+
196
+ // Initialize game
197
+ initGame();
198
+
199
+ // Event listeners
200
+ document.addEventListener('keydown', handleKeyPress);
201
+ restartBtn.addEventListener('click', resetGame);
202
+ weaponIcons.forEach(icon => {
203
+ icon.addEventListener('click', () => {
204
+ const weapon = icon.dataset.weapon;
205
+ if (ammo[weapon] > 0 || weapon === 'pistol') {
206
+ selectWeapon(weapon);
207
+ }
208
+ });
209
+ });
210
+
211
+ // Game loop
212
+ let lastTime = 0;
213
+ function gameLoop(timestamp) {
214
+ if (!gameRunning) return;
215
+
216
+ const deltaTime = timestamp - lastTime;
217
+ lastTime = timestamp;
218
+
219
+ updatePlayer(deltaTime);
220
+ updateGhosts(deltaTime);
221
+ updateBullets();
222
+ updateMines();
223
+ checkCollisions();
224
+ checkWinCondition();
225
+
226
+ requestAnimationFrame(gameLoop);
227
+ }
228
+
229
+ requestAnimationFrame(gameLoop);
230
+
231
+ // Game functions
232
+ function initGame() {
233
+ // Set up game container
234
+ gameContainer.style.width = `${GRID_SIZE * CELL_SIZE}px`;
235
+ gameContainer.style.height = `${GRID_SIZE * CELL_SIZE}px`;
236
+
237
+ // Generate maze
238
+ generateMaze();
239
+
240
+ // Create player
241
+ createPlayer();
242
+
243
+ // Create initial ghosts
244
+ createGhosts(3);
245
+
246
+ // Create initial pellets
247
+ createPellets();
248
+
249
+ // Create powerups
250
+ createPowerups();
251
+
252
+ // Update displays
253
+ updateDisplays();
254
+ }
255
+
256
+ function generateMaze() {
257
+ // Clear previous elements
258
+ gameContainer.innerHTML = '';
259
+ walls = [];
260
+
261
+ // Create border walls
262
+ for (let y = 0; y < GRID_SIZE; y++) {
263
+ for (let x = 0; x < GRID_SIZE; x++) {
264
+ if (x === 0 || y === 0 || x === GRID_SIZE - 1 || y === GRID_SIZE - 1) {
265
+ createWall(x, y);
266
+ } else if (Math.random() < 0.15 && !(x < 3 && y < 3)) {
267
+ createWall(x, y);
268
+ }
269
+ }
270
+ }
271
+
272
+ // Ensure some paths
273
+ for (let x = 1; x < GRID_SIZE - 1; x++) {
274
+ if (!walls.some(w => w.x === x && w.y === 1)) {
275
+ createPath(x, 1);
276
+ }
277
+ if (!walls.some(w => w.x === x && w.y === GRID_SIZE - 2)) {
278
+ createPath(x, GRID_SIZE - 2);
279
+ }
280
+ }
281
+
282
+ for (let y = 1; y < GRID_SIZE - 1; y++) {
283
+ if (!walls.some(w => w.x === 1 && w.y === y)) {
284
+ createPath(1, y);
285
+ }
286
+ if (!walls.some(w => w.x === GRID_SIZE - 2 && w.y === y)) {
287
+ createPath(GRID_SIZE - 2, y);
288
+ }
289
+ }
290
+ }
291
+
292
+ function createWall(x, y) {
293
+ const wall = document.createElement('div');
294
+ wall.className = 'wall absolute';
295
+ wall.style.width = `${CELL_SIZE}px`;
296
+ wall.style.height = `${CELL_SIZE}px`;
297
+ wall.style.left = `${x * CELL_SIZE}px`;
298
+ wall.style.top = `${y * CELL_SIZE}px`;
299
+ gameContainer.appendChild(wall);
300
+ walls.push({ x, y });
301
+ }
302
+
303
+ function createPath(x, y) {
304
+ const path = document.createElement('div');
305
+ path.className = 'path absolute';
306
+ path.style.width = `${CELL_SIZE}px`;
307
+ path.style.height = `${CELL_SIZE}px`;
308
+ path.style.left = `${x * CELL_SIZE}px`;
309
+ path.style.top = `${y * CELL_SIZE}px`;
310
+ gameContainer.appendChild(path);
311
+ }
312
+
313
+ function createPlayer() {
314
+ const player = document.createElement('div');
315
+ player.id = 'player';
316
+ player.className = 'absolute bg-yellow-400 rounded-full';
317
+ player.style.width = `${CELL_SIZE - 4}px`;
318
+ player.style.height = `${CELL_SIZE - 4}px`;
319
+ player.style.left = `${playerPosition.x * CELL_SIZE + 2}px`;
320
+ player.style.top = `${playerPosition.y * CELL_SIZE + 2}px`;
321
+ gameContainer.appendChild(player);
322
+
323
+ // Add mouth effect based on direction
324
+ updatePlayerMouth();
325
+ }
326
+
327
+ function updatePlayerMouth() {
328
+ const player = document.getElementById('player');
329
+ player.innerHTML = '';
330
+
331
+ const mouth = document.createElement('div');
332
+ mouth.className = 'absolute bg-black rounded-full';
333
+
334
+ switch(playerDirection) {
335
+ case 'right':
336
+ mouth.style.width = `${CELL_SIZE / 3}px`;
337
+ mouth.style.height = `${CELL_SIZE / 3}px`;
338
+ mouth.style.right = '0';
339
+ mouth.style.top = '50%';
340
+ mouth.style.transform = 'translateY(-50%)';
341
+ break;
342
+ case 'left':
343
+ mouth.style.width = `${CELL_SIZE / 3}px`;
344
+ mouth.style.height = `${CELL_SIZE / 3}px`;
345
+ mouth.style.left = '0';
346
+ mouth.style.top = '50%';
347
+ mouth.style.transform = 'translateY(-50%)';
348
+ break;
349
+ case 'up':
350
+ mouth.style.width = `${CELL_SIZE / 3}px`;
351
+ mouth.style.height = `${CELL_SIZE / 3}px`;
352
+ mouth.style.top = '0';
353
+ mouth.style.left = '50%';
354
+ mouth.style.transform = 'translateX(-50%)';
355
+ break;
356
+ case 'down':
357
+ mouth.style.width = `${CELL_SIZE / 3}px`;
358
+ mouth.style.height = `${CELL_SIZE / 3}px`;
359
+ mouth.style.bottom = '0';
360
+ mouth.style.left = '50%';
361
+ mouth.style.transform = 'translateX(-50%)';
362
+ break;
363
+ }
364
+
365
+ player.appendChild(mouth);
366
+ }
367
+
368
+ function createGhosts(count) {
369
+ ghosts = [];
370
+
371
+ for (let i = 0; i < count; i++) {
372
+ let x, y;
373
+ do {
374
+ x = Math.floor(Math.random() * (GRID_SIZE - 4)) + 2;
375
+ y = Math.floor(Math.random() * (GRID_SIZE - 4)) + 2;
376
+ } while (walls.some(w => w.x === x && w.y === y) ||
377
+ (x === playerPosition.x && y === playerPosition.y));
378
+
379
+ const ghost = {
380
+ x,
381
+ y,
382
+ id: `ghost-${i}`,
383
+ direction: ['up', 'down', 'left', 'right'][Math.floor(Math.random() * 4)],
384
+ speed: GHOST_SPEED + Math.random() * 50,
385
+ color: ['red', 'pink', 'cyan', 'orange'][i % 4]
386
+ };
387
+
388
+ ghosts.push(ghost);
389
+
390
+ const ghostElement = document.createElement('div');
391
+ ghostElement.id = ghost.id;
392
+ ghostElement.className = `ghost absolute rounded-full`;
393
+ ghostElement.style.backgroundColor = ghost.color;
394
+ ghostElement.style.width = `${CELL_SIZE - 4}px`;
395
+ ghostElement.style.height = `${CELL_SIZE - 4}px`;
396
+ ghostElement.style.left = `${ghost.x * CELL_SIZE + 2}px`;
397
+ ghostElement.style.top = `${ghost.y * CELL_SIZE + 2}px`;
398
+
399
+ // Add eyes
400
+ const leftEye = document.createElement('div');
401
+ leftEye.className = 'absolute bg-white rounded-full';
402
+ leftEye.style.width = `${CELL_SIZE / 4}px`;
403
+ leftEye.style.height = `${CELL_SIZE / 4}px`;
404
+ leftEye.style.left = `${CELL_SIZE / 4}px`;
405
+ leftEye.style.top = `${CELL_SIZE / 4}px`;
406
+
407
+ const rightEye = leftEye.cloneNode();
408
+ rightEye.style.left = `${CELL_SIZE / 2}px`;
409
+
410
+ ghostElement.appendChild(leftEye);
411
+ ghostElement.appendChild(rightEye);
412
+
413
+ gameContainer.appendChild(ghostElement);
414
+ }
415
+ }
416
+
417
+ function createPellets() {
418
+ pellets = [];
419
+
420
+ for (let y = 1; y < GRID_SIZE - 1; y++) {
421
+ for (let x = 1; x < GRID_SIZE - 1; x++) {
422
+ if (!walls.some(w => w.x === x && w.y === y) &&
423
+ !(x === playerPosition.x && y === playerPosition.y) &&
424
+ !ghosts.some(g => g.x === x && g.y === y)) {
425
+
426
+ // Skip some cells to not overcrowd
427
+ if (Math.random() > 0.3) {
428
+ pellets.push({ x, y });
429
+
430
+ const pellet = document.createElement('div');
431
+ pellet.className = 'absolute bg-white rounded-full';
432
+ pellet.style.width = `${CELL_SIZE / 4}px`;
433
+ pellet.style.height = `${CELL_SIZE / 4}px`;
434
+ pellet.style.left = `${x * CELL_SIZE + CELL_SIZE / 2 - CELL_SIZE / 8}px`;
435
+ pellet.style.top = `${y * CELL_SIZE + CELL_SIZE / 2 - CELL_SIZE / 8}px`;
436
+ pellet.dataset.x = x;
437
+ pellet.dataset.y = y;
438
+ gameContainer.appendChild(pellet);
439
+ }
440
+ }
441
+ }
442
+ }
443
+ }
444
+
445
+ function createPowerups() {
446
+ powerups = [];
447
+
448
+ // Create 2 powerups in random positions
449
+ for (let i = 0; i < 2; i++) {
450
+ let x, y;
451
+ do {
452
+ x = Math.floor(Math.random() * (GRID_SIZE - 4)) + 2;
453
+ y = Math.floor(Math.random() * (GRID_SIZE - 4)) + 2;
454
+ } while (walls.some(w => w.x === x && w.y === y) ||
455
+ (x === playerPosition.x && y === playerPosition.y) ||
456
+ ghosts.some(g => g.x === x && g.y === y));
457
+
458
+ powerups.push({ x, y });
459
+
460
+ const powerup = document.createElement('div');
461
+ powerup.className = 'powerup absolute bg-yellow-400 rounded-full';
462
+ powerup.style.width = `${CELL_SIZE / 2}px`;
463
+ powerup.style.height = `${CELL_SIZE / 2}px`;
464
+ powerup.style.left = `${x * CELL_SIZE + CELL_SIZE / 4}px`;
465
+ powerup.style.top = `${y * CELL_SIZE + CELL_SIZE / 4}px`;
466
+ powerup.dataset.x = x;
467
+ powerup.dataset.y = y;
468
+ gameContainer.appendChild(powerup);
469
+ }
470
+ }
471
+
472
+ function handleKeyPress(e) {
473
+ if (!gameRunning) return;
474
+
475
+ switch(e.key) {
476
+ case 'ArrowUp':
477
+ case 'w':
478
+ case 'W':
479
+ nextDirection = 'up';
480
+ break;
481
+ case 'ArrowDown':
482
+ case 's':
483
+ case 'S':
484
+ nextDirection = 'down';
485
+ break;
486
+ case 'ArrowLeft':
487
+ case 'a':
488
+ case 'A':
489
+ nextDirection = 'left';
490
+ break;
491
+ case 'ArrowRight':
492
+ case 'd':
493
+ case 'D':
494
+ nextDirection = 'right';
495
+ break;
496
+ case ' ':
497
+ shoot();
498
+ break;
499
+ case '1':
500
+ selectWeapon('pistol');
501
+ break;
502
+ case '2':
503
+ selectWeapon('shotgun');
504
+ break;
505
+ case '3':
506
+ selectWeapon('laser');
507
+ break;
508
+ case '4':
509
+ selectWeapon('rocket');
510
+ break;
511
+ case '5':
512
+ selectWeapon('mine');
513
+ break;
514
+ }
515
+ }
516
+
517
+ function selectWeapon(weapon) {
518
+ if (ammo[weapon] <= 0 && weapon !== 'pistol') return;
519
+
520
+ currentWeapon = weapon;
521
+ weaponDisplay.textContent = weapon.toUpperCase();
522
+
523
+ // Update weapon icons
524
+ weaponIcons.forEach(icon => {
525
+ if (icon.dataset.weapon === weapon) {
526
+ icon.classList.add('border-yellow-500');
527
+ icon.classList.remove('border-gray-500');
528
+ } else {
529
+ icon.classList.add('border-gray-500');
530
+ icon.classList.remove('border-yellow-500');
531
+ }
532
+ });
533
+
534
+ updateDisplays();
535
+ }
536
+
537
+ function shoot() {
538
+ if (ammo[currentWeapon] <= 0 && currentWeapon !== 'pistol') return;
539
+
540
+ if (currentWeapon !== 'pistol') {
541
+ ammo[currentWeapon]--;
542
+ updateDisplays();
543
+ }
544
+
545
+ switch(currentWeapon) {
546
+ case 'pistol':
547
+ createBullet(playerPosition.x, playerPosition.y, playerDirection);
548
+ break;
549
+ case 'shotgun':
550
+ // Create 3 bullets in a spread
551
+ createBullet(playerPosition.x, playerPosition.y, playerDirection);
552
+ createBullet(playerPosition.x, playerPosition.y, rotateDirection(playerDirection, -15));
553
+ createBullet(playerPosition.x, playerPosition.y, rotateDirection(playerDirection, 15));
554
+ break;
555
+ case 'laser':
556
+ createLaser(playerPosition.x, playerPosition.y, playerDirection);
557
+ break;
558
+ case 'rocket':
559
+ createRocket(playerPosition.x, playerPosition.y, playerDirection);
560
+ break;
561
+ case 'mine':
562
+ placeMine(playerPosition.x, playerPosition.y);
563
+ break;
564
+ }
565
+ }
566
+
567
+ function rotateDirection(direction, degrees) {
568
+ const directions = ['up', 'right', 'down', 'left'];
569
+ let index = directions.indexOf(direction);
570
+ const steps = Math.round(degrees / 90);
571
+ index = (index + steps + directions.length) % directions.length;
572
+ return directions[index];
573
+ }
574
+
575
+ function createBullet(x, y, direction) {
576
+ const bullet = {
577
+ x: x * CELL_SIZE + CELL_SIZE / 2,
578
+ y: y * CELL_SIZE + CELL_SIZE / 2,
579
+ direction,
580
+ speed: BULLET_SPEED,
581
+ id: `bullet-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
582
+ type: 'bullet'
583
+ };
584
+
585
+ bullets.push(bullet);
586
+
587
+ const bulletElement = document.createElement('div');
588
+ bulletElement.id = bullet.id;
589
+ bulletElement.className = 'bullet absolute bg-yellow-400 rounded-full';
590
+ bulletElement.style.width = `${CELL_SIZE / 4}px`;
591
+ bulletElement.style.height = `${CELL_SIZE / 4}px`;
592
+ bulletElement.style.left = `${bullet.x - CELL_SIZE / 8}px`;
593
+ bulletElement.style.top = `${bullet.y - CELL_SIZE / 8}px`;
594
+ gameContainer.appendChild(bulletElement);
595
+ }
596
+
597
+ function createLaser(x, y, direction) {
598
+ const laser = {
599
+ x: x * CELL_SIZE + CELL_SIZE / 2,
600
+ y: y * CELL_SIZE + CELL_SIZE / 2,
601
+ direction,
602
+ distance: 0,
603
+ maxDistance: CELL_SIZE * 10,
604
+ id: `laser-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
605
+ type: 'laser'
606
+ };
607
+
608
+ bullets.push(laser);
609
+
610
+ const laserElement = document.createElement('div');
611
+ laserElement.id = laser.id;
612
+ laserElement.className = 'bullet absolute bg-red-500';
613
+ laserElement.style.width = direction === 'left' || direction === 'right' ? '2px' : `${CELL_SIZE / 2}px`;
614
+ laserElement.style.height = direction === 'up' || direction === 'down' ? '2px' : `${CELL_SIZE / 2}px`;
615
+ updateLaserPosition(laser, laserElement);
616
+ gameContainer.appendChild(laserElement);
617
+
618
+ // Laser only lasts for a short time
619
+ setTimeout(() => {
620
+ if (laserElement.parentNode) {
621
+ gameContainer.removeChild(laserElement);
622
+ bullets = bullets.filter(b => b.id !== laser.id);
623
+ }
624
+ }, 300);
625
+ }
626
+
627
+ function createRocket(x, y, direction) {
628
+ const rocket = {
629
+ x: x * CELL_SIZE + CELL_SIZE / 2,
630
+ y: y * CELL_SIZE + CELL_SIZE / 2,
631
+ direction,
632
+ speed: BULLET_SPEED * 0.8,
633
+ id: `rocket-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`,
634
+ type: 'rocket'
635
+ };
636
+
637
+ bullets.push(rocket);
638
+
639
+ const rocketElement = document.createElement('div');
640
+ rocketElement.id = rocket.id;
641
+ rocketElement.className = 'bullet absolute';
642
+ rocketElement.innerHTML = '<i class="fas fa-rocket text-orange-500"></i>';
643
+ rocketElement.style.fontSize = `${CELL_SIZE / 2}px`;
644
+ rocketElement.style.transform = `rotate(${direction === 'right' ? 0 : direction === 'left' ? 180 : direction === 'up' ? -90 : 90}deg)`;
645
+ rocketElement.style.left = `${rocket.x - CELL_SIZE / 4}px`;
646
+ rocketElement.style.top = `${rocket.y - CELL_SIZE / 4}px`;
647
+ gameContainer.appendChild(rocketElement);
648
+ }
649
+
650
+ function placeMine(x, y) {
651
+ // Check if there's already a mine here
652
+ if (mines.some(m => m.x === x && m.y === y)) return;
653
+
654
+ const mine = {
655
+ x,
656
+ y,
657
+ id: `mine-${Date.now()}-${Math.random().toString(36).substr(2, 5)}`
658
+ };
659
+
660
+ mines.push(mine);
661
+
662
+ const mineElement = document.createElement('div');
663
+ mineElement.id = mine.id;
664
+ mineElement.className = 'absolute';
665
+ mineElement.innerHTML = '<i class="fas fa-land-mine-on text-gray-400"></i>';
666
+ mineElement.style.fontSize = `${CELL_SIZE / 2}px`;
667
+ mineElement.style.left = `${x * CELL_SIZE + CELL_SIZE / 4}px`;
668
+ mineElement.style.top = `${y * CELL_SIZE + CELL_SIZE / 4}px`;
669
+ gameContainer.appendChild(mineElement);
670
+ }
671
+
672
+ function updatePlayer(deltaTime) {
673
+ // Check if we can change direction
674
+ const nextX = playerPosition.x + (nextDirection === 'left' ? -1 : nextDirection === 'right' ? 1 : 0);
675
+ const nextY = playerPosition.y + (nextDirection === 'up' ? -1 : nextDirection === 'down' ? 1 : 0);
676
+
677
+ if (!walls.some(w => w.x === nextX && w.y === nextY)) {
678
+ playerDirection = nextDirection;
679
+ updatePlayerMouth();
680
+ }
681
+
682
+ // Move in current direction
683
+ const moveX = playerDirection === 'left' ? -1 : playerDirection === 'right' ? 1 : 0;
684
+ const moveY = playerDirection === 'up' ? -1 : playerDirection === 'down' ? 1 : 0;
685
+
686
+ const newX = playerPosition.x + moveX * (deltaTime / PLAYER_SPEED);
687
+ const newY = playerPosition.y + moveY * (deltaTime / PLAYER_SPEED);
688
+
689
+ // Check wall collisions
690
+ const cellX = Math.round(newX);
691
+ const cellY = Math.round(newY);
692
+
693
+ if (!walls.some(w => w.x === cellX && w.y === cellY)) {
694
+ playerPosition.x = newX;
695
+ playerPosition.y = newY;
696
+
697
+ // Wrap around edges
698
+ if (playerPosition.x < 0) playerPosition.x = GRID_SIZE - 1;
699
+ if (playerPosition.x >= GRID_SIZE) playerPosition.x = 0;
700
+ if (playerPosition.y < 0) playerPosition.y = GRID_SIZE - 1;
701
+ if (playerPosition.y >= GRID_SIZE) playerPosition.y = 0;
702
+
703
+ // Update player element
704
+ const player = document.getElementById('player');
705
+ player.style.left = `${playerPosition.x * CELL_SIZE + 2}px`;
706
+ player.style.top = `${playerPosition.y * CELL_SIZE + 2}px`;
707
+ }
708
+ }
709
+
710
+ function updateGhosts(deltaTime) {
711
+ ghosts.forEach(ghost => {
712
+ // Change direction randomly or when hitting a wall
713
+ if (Math.random() < 0.02 ||
714
+ walls.some(w =>
715
+ w.x === ghost.x + (ghost.direction === 'left' ? -1 : ghost.direction === 'right' ? 1 : 0) &&
716
+ w.y === ghost.y + (ghost.direction === 'up' ? -1 : ghost.direction === 'down' ? 1 : 0))) {
717
+
718
+ const directions = ['up', 'down', 'left', 'right'];
719
+ ghost.direction = directions[Math.floor(Math.random() * directions.length)];
720
+ }
721
+
722
+ // Move ghost
723
+ const moveX = ghost.direction === 'left' ? -1 : ghost.direction === 'right' ? 1 : 0;
724
+ const moveY = ghost.direction === 'up' ? -1 : ghost.direction === 'down' ? 1 : 0;
725
+
726
+ const newX = ghost.x + moveX * (deltaTime / ghost.speed);
727
+ const newY = ghost.y + moveY * (deltaTime / ghost.speed);
728
+
729
+ // Check wall collisions
730
+ const cellX = Math.round(newX);
731
+ const cellY = Math.round(newY);
732
+
733
+ if (!walls.some(w => w.x === cellX && w.y === cellY)) {
734
+ ghost.x = newX;
735
+ ghost.y = newY;
736
+
737
+ // Update ghost element
738
+ const ghostElement = document.getElementById(ghost.id);
739
+ if (ghostElement) {
740
+ ghostElement.style.left = `${ghost.x * CELL_SIZE + 2}px`;
741
+ ghostElement.style.top = `${ghost.y * CELL_SIZE + 2}px`;
742
+
743
+ // Update eyes direction
744
+ const eyes = ghostElement.querySelectorAll('div');
745
+ eyes.forEach(eye => {
746
+ eye.style.left = ghost.direction === 'left' ? `${CELL_SIZE / 4}px` :
747
+ ghost.direction === 'right' ? `${CELL_SIZE / 2}px` :
748
+ `${CELL_SIZE / 3}px`;
749
+ eye.style.top = ghost.direction === 'up' ? `${CELL_SIZE / 4}px` :
750
+ ghost.direction === 'down' ? `${CELL_SIZE / 2}px` :
751
+ `${CELL_SIZE / 3}px`;
752
+ });
753
+ }
754
+ }
755
+ });
756
+ }
757
+
758
+ function updateBullets() {
759
+ bullets.forEach(bullet => {
760
+ if (bullet.type === 'laser') {
761
+ // Laser grows until max distance
762
+ bullet.distance += BULLET_SPEED * 2;
763
+ if (bullet.distance > bullet.maxDistance) {
764
+ bullet.distance = bullet.maxDistance;
765
+ }
766
+
767
+ const laserElement = document.getElementById(bullet.id);
768
+ if (laserElement) {
769
+ updateLaserPosition(bullet, laserElement);
770
+ }
771
+ } else {
772
+ // Move bullet
773
+ const moveX = bullet.direction === 'left' ? -1 : bullet.direction === 'right' ? 1 : 0;
774
+ const moveY = bullet.direction === 'up' ? -1 : bullet.direction === 'down' ? 1 : 0;
775
+
776
+ bullet.x += moveX * bullet.speed;
777
+ bullet.y += moveY * bullet.speed;
778
+
779
+ // Update bullet element
780
+ const bulletElement = document.getElementById(bullet.id);
781
+ if (bulletElement) {
782
+ if (bullet.type === 'rocket') {
783
+ bulletElement.style.left = `${bullet.x - CELL_SIZE / 4}px`;
784
+ bulletElement.style.top = `${bullet.y - CELL_SIZE / 4}px`;
785
+ } else {
786
+ bulletElement.style.left = `${bullet.x - CELL_SIZE / 8}px`;
787
+ bulletElement.style.top = `${bullet.y - CELL_SIZE / 8}px`;
788
+ }
789
+ }
790
+ }
791
+
792
+ // Check if bullet is out of bounds
793
+ if (bullet.x < 0 || bullet.x > GRID_SIZE * CELL_SIZE ||
794
+ bullet.y < 0 || bullet.y > GRID_SIZE * CELL_SIZE) {
795
+
796
+ removeBullet(bullet.id);
797
+ }
798
+ });
799
+ }
800
+
801
+ function updateLaserPosition(laser, laserElement) {
802
+ const centerX = laser.x;
803
+ const centerY = laser.y;
804
+
805
+ if (laser.direction === 'left' || laser.direction === 'right') {
806
+ const length = laser.distance;
807
+ const left = laser.direction === 'left' ? centerX - length : centerX;
808
+ laserElement.style.left = `${left}px`;
809
+ laserElement.style.top = `${centerY - 1}px`;
810
+ laserElement.style.width = `${length}px`;
811
+ } else {
812
+ const length = laser.distance;
813
+ const top = laser.direction === 'up' ? centerY - length : centerY;
814
+ laserElement.style.left = `${centerX - 1}px`;
815
+ laserElement.style.top = `${top}px`;
816
+ laserElement.style.height = `${length}px`;
817
+ }
818
+ }
819
+
820
+ function updateMines() {
821
+ // Mines don't move, just check for explosions
822
+ }
823
+
824
+ function removeBullet(id) {
825
+ const bulletElement = document.getElementById(id);
826
+ if (bulletElement && bulletElement.parentNode) {
827
+ gameContainer.removeChild(bulletElement);
828
+ }
829
+ bullets = bullets.filter(b => b.id !== id);
830
+ }
831
+
832
+ function checkCollisions() {
833
+ // Check pellet collection
834
+ const playerCellX = Math.round(playerPosition.x);
835
+ const playerCellY = Math.round(playerPosition.y);
836
+
837
+ // Check pellets
838
+ const pelletIndex = pellets.findIndex(p => p.x === playerCellX && p.y === playerCellY);
839
+ if (pelletIndex !== -1) {
840
+ pellets.splice(pelletIndex, 1);
841
+ score += 10;
842
+
843
+ // Remove pellet element
844
+ const pelletElements = document.querySelectorAll(`[data-x="${playerCellX}"][data-y="${playerCellY}"]`);
845
+ pelletElements.forEach(el => {
846
+ if (el.parentNode) gameContainer.removeChild(el);
847
+ });
848
+
849
+ updateDisplays();
850
+ }
851
+
852
+ // Check powerups
853
+ const powerupIndex = powerups.findIndex(p => p.x === playerCellX && p.y === playerCellY);
854
+ if (powerupIndex !== -1) {
855
+ powerups.splice(powerupIndex, 1);
856
+ score += 50;
857
+
858
+ // Refill all ammo
859
+ Object.keys(ammo).forEach(key => {
860
+ if (key !== 'pistol') ammo[key] += 10;
861
+ });
862
+
863
+ // Remove powerup element
864
+ const powerupElements = document.querySelectorAll(`[data-x="${playerCellX}"][data-y="${playerCellY}"]`);
865
+ powerupElements.forEach(el => {
866
+ if (el.parentNode) gameContainer.removeChild(el);
867
+ });
868
+
869
+ updateDisplays();
870
+ }
871
+
872
+ // Check ghost collisions
873
+ ghosts.forEach(ghost => {
874
+ const ghostCellX = Math.round(ghost.x);
875
+ const ghostCellY = Math.round(ghost.y);
876
+
877
+ if (ghostCellX === playerCellX && ghostCellY === playerCellY) {
878
+ loseLife();
879
+ }
880
+ });
881
+
882
+ // Check bullet collisions with ghosts
883
+ bullets.forEach(bullet => {
884
+ const bulletCellX = Math.round(bullet.x / CELL_SIZE);
885
+ const bulletCellY = Math.round(bullet.y / CELL_SIZE);
886
+
887
+ if (bullet.type === 'laser') {
888
+ // Laser hits everything in its path
889
+ const hitGhosts = ghosts.filter(ghost => {
890
+ const ghostCellX = Math.round(ghost.x);
891
+ const ghostCellY = Math.round(ghost.y);
892
+
893
+ if (bullet.direction === 'left' || bullet.direction === 'right') {
894
+ return ghostCellY === bulletCellY &&
895
+ ((bullet.direction === 'left' && ghostCellX <= bulletCellX) ||
896
+ (bullet.direction === 'right' && ghostCellX >= bulletCellX));
897
+ } else {
898
+ return ghostCellX === bulletCellX &&
899
+ ((bullet.direction === 'up' && ghostCellY <= bulletCellY) ||
900
+ (bullet.direction === 'down' && ghostCellY >= bulletCellY));
901
+ }
902
+ });
903
+
904
+ hitGhosts.forEach(ghost => {
905
+ killGhost(ghost);
906
+ });
907
+
908
+ if (hitGhosts.length > 0) {
909
+ removeBullet(bullet.id);
910
+ }
911
+ } else if (bullet.type === 'rocket') {
912
+ // Rocket explodes when hitting a ghost or wall
913
+ const hitGhost = ghosts.find(ghost => {
914
+ const ghostCellX = Math.round(ghost.x);
915
+ const ghostCellY = Math.round(ghost.y);
916
+ return ghostCellX === bulletCellX && ghostCellY === bulletCellY;
917
+ });
918
+
919
+ const hitWall = walls.some(w => w.x === bulletCellX && w.y === bulletCellY);
920
+
921
+ if (hitGhost || hitWall) {
922
+ // Explosion effect
923
+ createExplosion(bulletCellX, bulletCellY);
924
+ removeBullet(bullet.id);
925
+
926
+ // Kill ghosts in 3x3 area
927
+ for (let y = bulletCellY - 1; y <= bulletCellY + 1; y++) {
928
+ for (let x = bulletCellX - 1; x <= bulletCellX + 1; x++) {
929
+ const ghostIndex = ghosts.findIndex(g =>
930
+ Math.round(g.x) === x && Math.round(g.y) === y);
931
+
932
+ if (ghostIndex !== -1) {
933
+ killGhost(ghosts[ghostIndex]);
934
+ }
935
+ }
936
+ }
937
+ }
938
+ } else {
939
+ // Regular bullet hits single ghost
940
+ const ghostIndex = ghosts.findIndex(ghost => {
941
+ const ghostCellX = Math.round(ghost.x);
942
+ const ghostCellY = Math.round(ghost.y);
943
+ return ghostCellX === bulletCellX && ghostCellY === bulletCellY;
944
+ });
945
+
946
+ if (ghostIndex !== -1) {
947
+ killGhost(ghosts[ghostIndex]);
948
+ removeBullet(bullet.id);
949
+ }
950
+ }
951
+
952
+ // Check bullet collisions with walls
953
+ if (walls.some(w => w.x === bulletCellX && w.y === bulletCellY)) {
954
+ removeBullet(bullet.id);
955
+ }
956
+ });
957
+
958
+ // Check mine explosions
959
+ mines.forEach(mine => {
960
+ const mineCellX = mine.x;
961
+ const mineCellY = mine.y;
962
+
963
+ // Check if player stepped on mine
964
+ if (playerCellX === mineCellX && playerCellY === mineCellY) {
965
+ createExplosion(mineCellX, mineCellY);
966
+ removeMine(mine.id);
967
+ loseLife();
968
+ }
969
+
970
+ // Check if ghost stepped on mine
971
+ const ghostIndex = ghosts.findIndex(ghost =>
972
+ Math.round(ghost.x) === mineCellX && Math.round(ghost.y) === mineCellY);
973
+
974
+ if (ghostIndex !== -1) {
975
+ createExplosion(mineCellX, mineCellY);
976
+ removeMine(mine.id);
977
+ killGhost(ghosts[ghostIndex]);
978
+ }
979
+ });
980
+ }
981
+
982
+ function createExplosion(x, y) {
983
+ const explosion = document.createElement('div');
984
+ explosion.className = 'absolute bg-orange-500 rounded-full';
985
+ explosion.style.width = `${CELL_SIZE * 3}px`;
986
+ explosion.style.height = `${CELL_SIZE * 3}px`;
987
+ explosion.style.left = `${x * CELL_SIZE - CELL_SIZE}px`;
988
+ explosion.style.top = `${y * CELL_SIZE - CELL_SIZE}px`;
989
+ explosion.style.opacity = '0.7';
990
+ explosion.style.transform = 'scale(0)';
991
+ explosion.style.transition = 'transform 0.3s ease-out, opacity 0.3s ease-out';
992
+ gameContainer.appendChild(explosion);
993
+
994
+ // Animate explosion
995
+ setTimeout(() => {
996
+ explosion.style.transform = 'scale(1)';
997
+ explosion.style.opacity = '0';
998
+ }, 10);
999
+
1000
+ // Remove after animation
1001
+ setTimeout(() => {
1002
+ if (explosion.parentNode) gameContainer.removeChild(explosion);
1003
+ }, 500);
1004
+ }
1005
+
1006
+ function removeMine(id) {
1007
+ const mineElement = document.getElementById(id);
1008
+ if (mineElement && mineElement.parentNode) {
1009
+ gameContainer.removeChild(mineElement);
1010
+ }
1011
+ mines = mines.filter(m => m.id !== id);
1012
+ }
1013
+
1014
+ function killGhost(ghost) {
1015
+ score += 100;
1016
+
1017
+ // Remove ghost element
1018
+ const ghostElement = document.getElementById(ghost.id);
1019
+ if (ghostElement && ghostElement.parentNode) {
1020
+ // Death animation
1021
+ ghostElement.style.transform = 'scale(1.5)';
1022
+ ghostElement.style.opacity = '0';
1023
+ ghostElement.style.transition = 'all 0.3s ease-out';
1024
+
1025
+ setTimeout(() => {
1026
+ if (ghostElement.parentNode) gameContainer.removeChild(ghostElement);
1027
+ }, 300);
1028
+ }
1029
+
1030
+ // Remove from array
1031
+ ghosts = ghosts.filter(g => g.id !== ghost.id);
1032
+
1033
+ updateDisplays();
1034
+ }
1035
+
1036
+ function loseLife() {
1037
+ lives--;
1038
+ updateDisplays();
1039
+
1040
+ if (lives <= 0) {
1041
+ gameOver(false);
1042
+ } else {
1043
+ // Reset player position
1044
+ playerPosition = { x: 1, y: 1 };
1045
+ const player = document.getElementById('player');
1046
+ player.style.left = `${playerPosition.x * CELL_SIZE + 2}px`;
1047
+ player.style.top = `${playerPosition.y * CELL_SIZE + 2}px`;
1048
+
1049
+ // Brief invulnerability
1050
+ player.style.opacity = '0.5';
1051
+ setTimeout(() => {
1052
+ player.style.opacity = '1';
1053
+ }, 1000);
1054
+ }
1055
+ }
1056
+
1057
+ function checkWinCondition() {
1058
+ if (pellets.length === 0 && powerups.length === 0) {
1059
+ gameOver(true);
1060
+ }
1061
+ }
1062
+
1063
+ function gameOver(won) {
1064
+ gameRunning = false;
1065
+
1066
+ overlayTitle.textContent = won ? 'VICTORY!' : 'GAME OVER';
1067
+ overlayTitle.className = won ? 'text-3xl font-bold mb-4 text-green-400' : 'text-3xl font-bold mb-4 text-red-400';
1068
+ finalScore.textContent = score;
1069
+
1070
+ if (won) {
1071
+ overlayMessage.innerHTML = `You cleared the maze with <span class="text-green-400">${lives}</span> lives remaining!`;
1072
+ } else {
1073
+ overlayMessage.innerHTML = 'You were defeated by the ghosts!';
1074
+ }
1075
+
1076
+ gameOverlay.classList.remove('hidden');
1077
+ }
1078
+
1079
+ function updateDisplays() {
1080
+ scoreDisplay.textContent = score;
1081
+ livesDisplay.textContent = lives;
1082
+ weaponDisplay.textContent = currentWeapon.toUpperCase();
1083
+ ammoDisplay.textContent = ammo[currentWeapon] === Infinity ? '∞' : ammo[currentWeapon];
1084
+
1085
+ // Update weapon icons to show ammo
1086
+ weaponIcons.forEach(icon => {
1087
+ const weapon = icon.dataset.weapon;
1088
+ if (weapon !== 'pistol') {
1089
+ const ammoText = document.createElement('span');
1090
+ ammoText.className = 'text-xs mt-1';
1091
+ ammoText.textContent = ammo[weapon];
1092
+
1093
+ // Remove existing ammo display if any
1094
+ const existingAmmo = icon.querySelector('.text-xs');
1095
+ if (existingAmmo) icon.removeChild(existingAmmo);
1096
+
1097
+ icon.appendChild(ammoText);
1098
+ }
1099
+ });
1100
+ }
1101
+
1102
+ function resetGame() {
1103
+ // Reset game state
1104
+ score = 0;
1105
+ lives = 3;
1106
+ gameRunning = true;
1107
+ playerDirection = 'right';
1108
+ nextDirection = 'right';
1109
+ playerPosition = { x: 1, y: 1 };
1110
+ ghosts = [];
1111
+ bullets = [];
1112
+ powerups = [];
1113
+ pellets = [];
1114
+ mines = [];
1115
+ currentWeapon = 'pistol';
1116
+ ammo = {
1117
+ pistol: Infinity,
1118
+ shotgun: 20,
1119
+ laser: 30,
1120
+ rocket: 5,
1121
+ mine: 3
1122
+ };
1123
+
1124
+ // Hide overlay
1125
+ gameOverlay.classList.add('hidden');
1126
+
1127
+ // Reinitialize game
1128
+ initGame();
1129
+
1130
+ // Restart game loop
1131
+ lastTime = 0;
1132
+ requestAnimationFrame(gameLoop);
1133
+ }
1134
+ });
1135
+ </script>
1136
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ILLERRAPS/weapon-pac" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1137
+ </html>
prompts.txt ADDED
File without changes