bbc123321 commited on
Commit
51f3ab7
·
verified ·
1 Parent(s): dd19369

Manual changes saved

Browse files
Files changed (1) hide show
  1. index.html +606 -272
index.html CHANGED
@@ -1,294 +1,628 @@
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>BattleZone Royale</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
9
- <script src="https://unpkg.com/feather-icons"></script>
10
- <style>
11
- #gameCanvas {
12
- background-image: url('http://static.photos/nature/1200x630/42');
13
- background-size: cover;
14
- background-position: center;
15
- box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
16
- }
17
- .biome-selector {
18
- transition: all 0.3s ease;
19
- }
20
- .biome-selector:hover {
21
- transform: scale(1.05);
22
- box-shadow: 0 0 15px rgba(255, 215, 0, 0.5);
23
- }
24
- .storm-animation {
25
- animation: stormPulse 3s infinite;
26
- }
27
- @keyframes stormPulse {
28
- 0% { box-shadow: 0 0 10px rgba(100, 149, 237, 0.5); }
29
- 50% { box-shadow: 0 0 30px rgba(100, 149, 237, 0.8); }
30
- 100% { box-shadow: 0 0 10px rgba(100, 149, 237, 0.5); }
31
- }
32
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  </head>
34
- <body class="bg-gray-900 text-white font-mono">
35
- <div class="container mx-auto px-4 py-8">
36
- <!-- Game Header -->
37
- <header class="flex justify-between items-center mb-8 border-b border-yellow-500 pb-4">
38
- <h1 class="text-4xl font-bold text-yellow-400 flex items-center">
39
- <i data-feather="target" class="mr-2"></i> BattleZone Royale
40
- </h1>
41
- <div class="flex space-x-4">
42
- <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
43
- <i data-feather="users" class="mr-2"></i>
44
- <span id="playerCount">1/100</span>
45
- </div>
46
- <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
47
- <i data-feather="clock" class="mr-2"></i>
48
- <span id="gameTimer">3:00</span>
49
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  </div>
51
- </header>
52
-
53
- <!-- Game Area -->
54
- <div class="flex flex-col lg:flex-row gap-8">
55
- <!-- Main Game Canvas -->
56
- <div class="flex-1 relative">
57
- <canvas id="gameCanvas" class="w-full h-96 lg:h-screen-80 rounded-xl border-4 border-gray-700"></canvas>
58
-
59
- <!-- Storm Warning -->
60
- <div id="stormWarning" class="hidden absolute top-4 left-1/2 transform -translate-x-1/2 bg-red-900 bg-opacity-80 text-white px-6 py-3 rounded-lg flex items-center storm-animation">
61
- <i data-feather="alert-circle" class="mr-2"></i>
62
- <span>STORM APPROACHING! MOVE TO SAFE ZONE!</span>
63
- </div>
64
-
65
- <!-- Death Screen -->
66
- <div id="deathScreen" class="hidden absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center rounded-xl">
67
- <i data-feather="skull" class="w-16 h-16 text-red-500 mb-4"></i>
68
- <h2 class="text-4xl font-bold text-red-500 mb-4">YOU DIED!</h2>
69
- <p class="text-xl mb-6">Better luck next time, soldier!</p>
70
- <button id="respawnBtn" class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg flex items-center">
71
- <i data-feather="refresh-cw" class="mr-2"></i> Respawn
72
- </button>
73
- </div>
74
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- <!-- Game Controls and Info -->
77
- <div class="w-full lg:w-80 bg-gray-800 rounded-xl p-6 h-fit">
78
- <!-- Landing Selection -->
79
- <div id="landingSelection" class="mb-8">
80
- <h2 class="text-2xl font-bold text-yellow-400 mb-4 flex items-center">
81
- <i data-feather="map-pin" class="mr-2"></i> Choose Landing Zone
82
- </h2>
83
- <div class="grid grid-cols-2 gap-4">
84
- <div class="biome-selector bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-yellow-800" data-biome="desert">
85
- <i data-feather="sun" class="text-yellow-300"></i>
86
- <h3 class="font-bold">Golden Dunes</h3>
87
- <p class="text-xs">High loot, high risk</p>
88
- </div>
89
- <div class="biome-selector bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-green-800" data-biome="forest">
90
- <i data-feather="tree" class="text-green-300"></i>
91
- <h3 class="font-bold">Shadow Forest</h3>
92
- <p class="text-xs">Good cover, medium loot</p>
93
- </div>
94
- <div class="biome-selector bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-blue-800" data-biome="oasis">
95
- <i data-feather="droplet" class="text-blue-300"></i>
96
- <h3 class="font-bold">Crystal Oasis</h3>
97
- <p class="text-xs">Medium loot, low risk</p>
98
- </div>
99
- <div class="biome-selector bg-gray-700 p-3 rounded-lg cursor-pointer hover:bg-purple-800" data-biome="ruins">
100
- <i data-feather="layers" class="text-purple-300"></i>
101
- <h3 class="font-bold">Ancient Ruins</h3>
102
- <p class="text-xs">Legendary loot, dangerous</p>
103
- </div>
104
- </div>
105
- </div>
106
-
107
- <!-- Player Stats -->
108
- <div class="mb-8">
109
- <h2 class="text-2xl font-bold text-yellow-400 mb-4 flex items-center">
110
- <i data-feather="activity" class="mr-2"></i> Player Stats
111
- </h2>
112
- <div class="space-y-3">
113
- <div class="flex justify-between">
114
- <span>Health:</span>
115
- <span id="playerHealth" class="font-bold">100%</span>
116
- </div>
117
- <div class="flex justify-between">
118
- <span>Armor:</span>
119
- <span id="playerArmor" class="font-bold">0%</span>
120
- </div>
121
- <div class="flex justify-between">
122
- <span>Kills:</span>
123
- <span id="playerKills" class="font-bold text-red-400">0</span>
124
- </div>
125
- </div>
126
- </div>
127
-
128
- <!-- Inventory -->
129
- <div class="mb-8">
130
- <h2 class="text-2xl font-bold text-yellow-400 mb-4 flex items-center">
131
- <i data-feather="briefcase" class="mr-2"></i> Inventory
132
- </h2>
133
- <div id="inventorySlots" class="grid grid-cols-3 gap-2">
134
- <!-- Will be populated with items -->
135
- </div>
136
- </div>
137
-
138
- <!-- Controls Info -->
139
- <div>
140
- <h2 class="text-2xl font-bold text-yellow-400 mb-4 flex items-center">
141
- <i data-feather="command" class="mr-2"></i> Controls
142
- </h2>
143
- <div class="space-y-2 text-sm">
144
- <div class="flex items-center">
145
- <span class="bg-gray-700 px-2 py-1 rounded mr-2">WASD</span>
146
- <span>Move character</span>
147
- </div>
148
- <div class="flex items-center">
149
- <span class="bg-gray-700 px-2 py-1 rounded mr-2">Mouse</span>
150
- <span>Aim and shoot</span>
151
- </div>
152
- <div class="flex items-center">
153
- <span class="bg-gray-700 px-2 py-1 rounded mr-2">E</span>
154
- <span>Loot chests/open doors</span>
155
- </div>
156
- <div class="flex items-center">
157
- <span class="bg-gray-700 px-2 py-1 rounded mr-2">1-5</span>
158
- <span>Switch weapons</span>
159
- </div>
160
- </div>
161
- </div>
162
  </div>
163
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  </div>
 
165
 
166
- <script>
167
- // Game variables
168
- let gameActive = false;
169
- let playerHealth = 100;
170
- let playerArmor = 0;
171
- let playerKills = 0;
172
- let gameTime = 180; // 3 minutes in seconds
173
- let stormActive = false;
174
- let selectedBiome = null;
175
-
176
- // Initialize canvas
177
- const canvas = document.getElementById('gameCanvas');
178
- const ctx = canvas.getContext('2d');
179
-
180
- // Set canvas size
181
- function resizeCanvas() {
182
- canvas.width = canvas.offsetWidth;
183
- canvas.height = canvas.offsetHeight;
184
- }
185
-
186
- window.addEventListener('resize', resizeCanvas);
187
- resizeCanvas();
188
-
189
- // Biome selection
190
- document.querySelectorAll('.biome-selector').forEach(selector => {
191
- selector.addEventListener('click', () => {
192
- selectedBiome = selector.getAttribute('data-biome');
193
- document.getElementById('landingSelection').classList.add('hidden');
194
- startGame();
195
- });
196
- });
197
-
198
- // Start game function
199
- function startGame() {
200
- gameActive = true;
201
- document.getElementById('stormWarning').classList.remove('hidden');
202
-
203
- // Start game timer
204
- const timerInterval = setInterval(() => {
205
- gameTime--;
206
- const minutes = Math.floor(gameTime / 60);
207
- const seconds = gameTime % 60;
208
- document.getElementById('gameTimer').textContent = `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
209
-
210
- // Activate storm after 1 minute
211
- if (gameTime === 120 && !stormActive) {
212
- stormActive = true;
213
- alert('The storm is closing in! Move to the safe zone!');
214
- }
215
-
216
- if (gameTime <= 0) {
217
- clearInterval(timerInterval);
218
- endGame();
219
- }
220
- }, 1000);
221
-
222
- // Start game loop
223
- gameLoop();
224
- }
225
 
226
- // Game loop
227
- function gameLoop() {
228
- if (!gameActive) return;
229
-
230
- // Clear canvas
231
- ctx.clearRect(0, 0, canvas.width, canvas.height);
232
-
233
- // Draw game elements here
234
- // (Character, enemies, loot, storm, etc.)
235
-
236
- requestAnimationFrame(gameLoop);
237
- }
238
 
239
- // End game function
240
- function endGame() {
241
- gameActive = false;
242
- if (playerHealth > 0) {
243
- alert('Congratulations! You survived the BattleZone!');
244
- }
245
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
- // Death function
248
- function playerDeath() {
249
- gameActive = false;
250
- document.getElementById('deathScreen').classList.remove('hidden');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
251
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
- // Respawn button
254
- document.getElementById('respawnBtn').addEventListener('click', () => {
255
- document.getElementById('deathScreen').classList.add('hidden');
256
- document.getElementById('landingSelection').classList.remove('hidden');
257
- resetPlayerStats();
258
- });
259
-
260
- // Reset player stats
261
- function resetPlayerStats() {
262
- playerHealth = 100;
263
- playerArmor = 0;
264
- playerKills = 0;
265
- updatePlayerStats();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
266
  }
 
 
 
 
267
 
268
- // Update player stats display
269
- function updatePlayerStats() {
270
- document.getElementById('playerHealth').textContent = `${playerHealth}%`;
271
- document.getElementById('playerArmor').textContent = `${playerArmor}%`;
272
- document.getElementById('playerKills').textContent = playerKills;
273
  }
274
 
275
- // Initialize inventory slots
276
- function initInventory() {
277
- const inventorySlots = document.getElementById('inventorySlots');
278
- inventorySlots.innerHTML = '';
279
-
280
- for (let i = 0; i < 6; i++) {
281
- const slot = document.createElement('div');
282
- slot.className = 'bg-gray-700 h-16 rounded-lg flex flex-col items-center justify-center text-xs';
283
- slot.innerHTML = '<i data-feather="box" class="text-gray-400"></i><span>Empty</span>';
284
- inventorySlots.appendChild(slot);
285
- }
286
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
 
288
- // Initialize
289
- feather.replace();
290
- initInventory();
291
- updatePlayerStats();
292
- </script>
 
293
  </body>
294
- </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" />
6
+ <title>BattleZone Royale</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <style>
10
+ html,
11
+ body,
12
+ #root {
13
+ height: 100%;
14
+ margin: 0;
15
+ background-color: #111827; /* Tailwind gray-900 */
16
+ color: white;
17
+ font-family: monospace;
18
+ }
19
+ #gameCanvas {
20
+ background-image: url('http://static.photos/nature/1200x630/42');
21
+ background-size: cover;
22
+ background-position: center;
23
+ display: block;
24
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
25
+ user-select: none;
26
+ cursor: crosshair;
27
+ }
28
+ .biome-selector {
29
+ transition: all 0.3s ease;
30
+ }
31
+ .biome-selector:hover {
32
+ transform: scale(1.05);
33
+ box-shadow: 0 0 15px rgba(255, 215, 0, 0.5);
34
+ }
35
+ .storm-animation {
36
+ animation: stormPulse 3s infinite;
37
+ }
38
+ @keyframes stormPulse {
39
+ 0% {
40
+ box-shadow: 0 0 10px rgba(100, 149, 237, 0.5);
41
+ }
42
+ 50% {
43
+ box-shadow: 0 0 30px rgba(100, 149, 237, 0.8);
44
+ }
45
+ 100% {
46
+ box-shadow: 0 0 10px rgba(100, 149, 237, 0.5);
47
+ }
48
+ }
49
+ #stormWarning {
50
+ z-index: 10;
51
+ }
52
+ #deathScreen {
53
+ z-index: 20;
54
+ }
55
+ /* Fullscreen canvas container */
56
+ #canvasContainer {
57
+ position: relative;
58
+ flex: 1;
59
+ display: flex;
60
+ justify-content: center;
61
+ align-items: center;
62
+ height: 100vh;
63
+ overflow: hidden;
64
+ }
65
+ </style>
66
  </head>
67
+ <body>
68
+ <div id="landingScreen" class="flex flex-col items-center justify-center h-screen bg-gray-900 p-6">
69
+ <h1 class="text-5xl font-bold text-yellow-400 mb-8 flex items-center">
70
+ <i data-feather="target" class="mr-2"></i> BattleZone Royale
71
+ </h1>
72
+ <h2 class="text-3xl font-semibold text-yellow-400 mb-6 flex items-center">
73
+ <i data-feather="map-pin" class="mr-2"></i> Choose Landing Zone
74
+ </h2>
75
+ <div class="grid grid-cols-2 gap-6 max-w-xl w-full">
76
+ <div
77
+ class="biome-selector bg-gray-700 p-6 rounded-lg cursor-pointer hover:bg-yellow-800 flex flex-col items-center"
78
+ data-biome="desert"
79
+ >
80
+ <i data-feather="sun" class="text-yellow-300 mb-2"></i>
81
+ <h3 class="font-bold text-lg">Golden Dunes</h3>
82
+ <p class="text-xs">High loot, high risk</p>
83
+ </div>
84
+ <div
85
+ class="biome-selector bg-gray-700 p-6 rounded-lg cursor-pointer hover:bg-green-800 flex flex-col items-center"
86
+ data-biome="forest"
87
+ >
88
+ <i data-feather="tree" class="text-green-300 mb-2"></i>
89
+ <h3 class="font-bold text-lg">Shadow Forest</h3>
90
+ <p class="text-xs">Good cover, medium loot</p>
91
+ </div>
92
+ <div
93
+ class="biome-selector bg-gray-700 p-6 rounded-lg cursor-pointer hover:bg-blue-800 flex flex-col items-center"
94
+ data-biome="oasis"
95
+ >
96
+ <i data-feather="droplet" class="text-blue-300 mb-2"></i>
97
+ <h3 class="font-bold text-lg">Crystal Oasis</h3>
98
+ <p class="text-xs">Medium loot, low risk</p>
99
+ </div>
100
+ <div
101
+ class="biome-selector bg-gray-700 p-6 rounded-lg cursor-pointer hover:bg-purple-800 flex flex-col items-center"
102
+ data-biome="ruins"
103
+ >
104
+ <i data-feather="layers" class="text-purple-300 mb-2"></i>
105
+ <h3 class="font-bold text-lg">Ancient Ruins</h3>
106
+ <p class="text-xs">Legendary loot, dangerous</p>
107
+ </div>
108
+ </div>
109
+ </div>
110
+
111
+ <div id="gameScreen" class="hidden h-screen flex flex-col">
112
+ <!-- Game Header -->
113
+ <header
114
+ class="flex justify-between items-center border-b border-yellow-500 px-6 py-4"
115
+ style="flex-shrink: 0;"
116
+ >
117
+ <h1 class="text-4xl font-bold text-yellow-400 flex items-center">
118
+ <i data-feather="target" class="mr-2"></i> BattleZone Royale
119
+ </h1>
120
+ <div class="flex space-x-4 text-white">
121
+ <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
122
+ <i data-feather="users" class="mr-2"></i>
123
+ <span id="playerCount">1/100</span>
124
+ </div>
125
+ <div class="bg-gray-800 px-4 py-2 rounded-lg flex items-center">
126
+ <i data-feather="clock" class="mr-2"></i>
127
+ <span id="gameTimer">5:00</span>
128
+ </div>
129
+ </div>
130
+ </header>
131
+
132
+ <div class="flex flex-1 overflow-hidden">
133
+ <!-- Main Game Canvas -->
134
+ <div
135
+ id="canvasContainer"
136
+ class="relative bg-gray-900 border-4 border-gray-700 rounded-xl max-w-full max-h-full"
137
+ >
138
+ <canvas id="gameCanvas"></canvas>
139
+
140
+ <!-- Storm Warning -->
141
+ <div
142
+ id="stormWarning"
143
+ class="hidden absolute top-6 left-1/2 transform -translate-x-1/2 bg-red-900 bg-opacity-80 text-white px-6 py-3 rounded-lg flex items-center storm-animation"
144
+ >
145
+ <i data-feather="alert-circle" class="mr-2"></i>
146
+ <span>STORM APPROACHING! MOVE TO SAFE ZONE!</span>
147
+ </div>
148
+
149
+ <!-- Death Screen -->
150
+ <div
151
+ id="deathScreen"
152
+ class="hidden absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center rounded-xl"
153
+ >
154
+ <i data-feather="skull" class="w-16 h-16 text-red-500 mb-4"></i>
155
+ <h2 class="text-4xl font-bold text-red-500 mb-4">YOU DIED!</h2>
156
+ <p class="text-xl mb-6">Better luck next time, soldier!</p>
157
+ <button
158
+ id="respawnBtn"
159
+ class="bg-yellow-500 hover:bg-yellow-600 text-black font-bold py-3 px-6 rounded-lg flex items-center"
160
+ >
161
+ <i data-feather="refresh-cw" class="mr-2"></i> Respawn
162
+ </button>
163
+ </div>
164
+ </div>
165
+
166
+ <!-- Game Controls and Info -->
167
+ <aside
168
+ class="w-80 bg-gray-800 rounded-xl p-6 overflow-y-auto flex-shrink-0 flex flex-col gap-8"
169
+ style="max-height: 100vh;"
170
+ >
171
+ <!-- Player Stats -->
172
+ <section>
173
+ <h2
174
+ class="text-2xl font-bold text-yellow-400 mb-4 flex items-center"
175
+ >
176
+ <i data-feather="activity" class="mr-2"></i> Player Stats
177
+ </h2>
178
+ <div class="space-y-3">
179
+ <div class="flex justify-between">
180
+ <span>Health:</span>
181
+ <span id="playerHealth" class="font-bold">100%</span>
182
  </div>
183
+ <div class="flex justify-between">
184
+ <span>Armor:</span>
185
+ <span id="playerArmor" class="font-bold">0%</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
186
  </div>
187
+ <div class="flex justify-between">
188
+ <span>Kills:</span>
189
+ <span id="playerKills" class="font-bold text-red-400">0</span>
190
+ </div>
191
+ </div>
192
+ </section>
193
+
194
+ <!-- Inventory -->
195
+ <section>
196
+ <h2
197
+ class="text-2xl font-bold text-yellow-400 mb-4 flex items-center"
198
+ >
199
+ <i data-feather="briefcase" class="mr-2"></i> Inventory
200
+ </h2>
201
+ <div
202
+ id="inventorySlots"
203
+ class="grid grid-cols-3 gap-2"
204
+ aria-label="Inventory slots"
205
+ ></div>
206
+ </section>
207
 
208
+ <!-- Controls Info -->
209
+ <section>
210
+ <h2
211
+ class="text-2xl font-bold text-yellow-400 mb-4 flex items-center"
212
+ >
213
+ <i data-feather="command" class="mr-2"></i> Controls
214
+ </h2>
215
+ <div class="space-y-2 text-sm">
216
+ <div class="flex items-center">
217
+ <span
218
+ class="bg-gray-700 px-2 py-1 rounded mr-2"
219
+ >WASD</span
220
+ >
221
+ <span>Move character</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  </div>
223
+ <div class="flex items-center">
224
+ <span
225
+ class="bg-gray-700 px-2 py-1 rounded mr-2"
226
+ >Mouse</span
227
+ >
228
+ <span>Aim and shoot</span>
229
+ </div>
230
+ <div class="flex items-center">
231
+ <span
232
+ class="bg-gray-700 px-2 py-1 rounded mr-2"
233
+ >E</span
234
+ >
235
+ <span>Loot chests/open doors</span>
236
+ </div>
237
+ <div class="flex items-center">
238
+ <span
239
+ class="bg-gray-700 px-2 py-1 rounded mr-2"
240
+ >1-5</span
241
+ >
242
+ <span>Switch weapons</span>
243
+ </div>
244
+ </div>
245
+ </section>
246
+ </aside>
247
  </div>
248
+ </div>
249
 
250
+ <script>
251
+ // Game variables
252
+ let gameActive = false;
253
+ let playerHealth = 100;
254
+ let playerArmor = 0;
255
+ let playerKills = 0;
256
+ let gameTime = 300; // 5 minutes in seconds
257
+ let stormActive = false;
258
+ let selectedBiome = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
 
260
+ // Canvas and context
261
+ const canvas = document.getElementById('gameCanvas');
262
+ const ctx = canvas.getContext('2d');
263
+ const stormWarningEl = document.getElementById('stormWarning');
264
+ const deathScreenEl = document.getElementById('deathScreen');
265
+ const landingScreenEl = document.getElementById('landingScreen');
266
+ const gameScreenEl = document.getElementById('gameScreen');
 
 
 
 
 
267
 
268
+ // Player and storm state
269
+ const player = {
270
+ x: 0,
271
+ y: 0,
272
+ radius: 15,
273
+ angle: 0,
274
+ speed: 3,
275
+ health: 100,
276
+ armor: 0,
277
+ kills: 0,
278
+ };
279
+
280
+ const storm = {
281
+ maxRadius: 600,
282
+ radius: 600,
283
+ centerX: 0,
284
+ centerY: 0,
285
+ damagePerSecond: 1,
286
+ closingSpeed: 0.5, // radius shrink per second
287
+ };
288
+
289
+ // Movement input
290
+ const keys = {
291
+ w: false,
292
+ a: false,
293
+ s: false,
294
+ d: false,
295
+ };
296
+
297
+ // Mouse
298
+ const mouse = {
299
+ x: 0,
300
+ y: 0,
301
+ canvasX: 0,
302
+ canvasY: 0,
303
+ };
304
+
305
+ // Resize canvas to fill container
306
+ function resizeCanvas() {
307
+ const container = document.getElementById('canvasContainer');
308
+ canvas.width = container.clientWidth;
309
+ canvas.height = container.clientHeight;
310
+ // Reset storm center to canvas center on resize
311
+ storm.centerX = canvas.width / 2;
312
+ storm.centerY = canvas.height / 2;
313
+ }
314
+ window.addEventListener('resize', resizeCanvas);
315
+
316
+ // Initialize player position center of canvas on start
317
+ function initPlayerPosition() {
318
+ player.x = canvas.width / 2;
319
+ player.y = canvas.height / 2;
320
+ }
321
+
322
+ // Update player stats UI
323
+ function updatePlayerStats() {
324
+ document.getElementById('playerHealth').textContent = `${playerHealth}%`;
325
+ document.getElementById('playerArmor').textContent = `${playerArmor}%`;
326
+ document.getElementById('playerKills').textContent = playerKills;
327
+ }
328
+
329
+ // Initialize inventory slots
330
+ function initInventory() {
331
+ const inventorySlots = document.getElementById('inventorySlots');
332
+ inventorySlots.innerHTML = '';
333
+
334
+ for (let i = 0; i < 6; i++) {
335
+ const slot = document.createElement('div');
336
+ slot.className =
337
+ 'bg-gray-700 h-16 rounded-lg flex flex-col items-center justify-center text-xs';
338
+ slot.innerHTML = '<i data-feather="box" class="text-gray-400"></i><span>Empty</span>';
339
+ inventorySlots.appendChild(slot);
340
+ }
341
+ }
342
+
343
+ // Handle keyboard input for movement
344
+ window.addEventListener('keydown', (e) => {
345
+ if (!gameActive) return;
346
+ const key = e.key.toLowerCase();
347
+ if (keys.hasOwnProperty(key)) {
348
+ keys[key] = true;
349
+ }
350
+ });
351
+ window.addEventListener('keyup', (e) => {
352
+ if (!gameActive) return;
353
+ const key = e.key.toLowerCase();
354
+ if (keys.hasOwnProperty(key)) {
355
+ keys[key] = false;
356
+ }
357
+ });
358
 
359
+ // Handle mouse movement for aiming
360
+ canvas.addEventListener('mousemove', (e) => {
361
+ const rect = canvas.getBoundingClientRect();
362
+ mouse.canvasX = e.clientX - rect.left;
363
+ mouse.canvasY = e.clientY - rect.top;
364
+
365
+ // Calculate angle from player to mouse position
366
+ const dx = mouse.canvasX - player.x;
367
+ const dy = mouse.canvasY - player.y;
368
+ player.angle = Math.atan2(dy, dx);
369
+ });
370
+
371
+ // Move player based on keys pressed, constrained within canvas
372
+ function movePlayer() {
373
+ if (!gameActive) return;
374
+ let dx = 0,
375
+ dy = 0;
376
+ if (keys.w) dy -= player.speed;
377
+ if (keys.s) dy += player.speed;
378
+ if (keys.a) dx -= player.speed;
379
+ if (keys.d) dx += player.speed;
380
+
381
+ // Normalize diagonal movement
382
+ if (dx !== 0 && dy !== 0) {
383
+ dx *= Math.SQRT1_2;
384
+ dy *= Math.SQRT1_2;
385
+ }
386
+
387
+ player.x += dx;
388
+ player.y += dy;
389
+
390
+ // Confine player inside canvas
391
+ player.x = Math.min(Math.max(player.radius, player.x), canvas.width - player.radius);
392
+ player.y = Math.min(Math.max(player.radius, player.y), canvas.height - player.radius);
393
+ }
394
+
395
+ // Draw player as a triangle pointing to aim direction
396
+ function drawPlayer() {
397
+ ctx.save();
398
+ ctx.translate(player.x, player.y);
399
+ ctx.rotate(player.angle);
400
+
401
+ // Player body (triangle)
402
+ ctx.fillStyle = 'yellow';
403
+ ctx.beginPath();
404
+ ctx.moveTo(20, 0);
405
+ ctx.lineTo(-15, -12);
406
+ ctx.lineTo(-15, 12);
407
+ ctx.closePath();
408
+ ctx.fill();
409
+
410
+ ctx.restore();
411
+ }
412
+
413
+ // Draw the shrinking storm circle with increasing damage indication
414
+ function drawStorm() {
415
+ ctx.save();
416
+
417
+ // Storm fill with transparent blue
418
+ const gradient = ctx.createRadialGradient(
419
+ storm.centerX,
420
+ storm.centerY,
421
+ storm.radius * 0.6,
422
+ storm.centerX,
423
+ storm.centerY,
424
+ storm.radius
425
+ );
426
+ gradient.addColorStop(0, 'rgba(100, 149, 237, 0.1)');
427
+ gradient.addColorStop(1, 'rgba(100, 149, 237, 0.6)');
428
+ ctx.fillStyle = gradient;
429
+ ctx.beginPath();
430
+ ctx.arc(storm.centerX, storm.centerY, storm.radius, 0, Math.PI * 2);
431
+ ctx.fill();
432
+
433
+ // Storm outline thickening and color shifting as radius shrinks
434
+ const stormProgress = 1 - storm.radius / storm.maxRadius; // 0 to 1
435
+ const outlineWidth = 10 + stormProgress * 20;
436
+ const redIntensity = Math.min(255, Math.floor(100 + stormProgress * 155));
437
+ ctx.strokeStyle = `rgba(${redIntensity}, 50, 150, 0.8)`;
438
+ ctx.lineWidth = outlineWidth;
439
+ ctx.beginPath();
440
+ ctx.arc(storm.centerX, storm.centerY, storm.radius, 0, Math.PI * 2);
441
+ ctx.stroke();
442
+
443
+ ctx.restore();
444
+ }
445
+
446
+ // Check if player is outside storm radius
447
+ function playerInStorm() {
448
+ const dx = player.x - storm.centerX;
449
+ const dy = player.y - storm.centerY;
450
+ const dist = Math.sqrt(dx * dx + dy * dy);
451
+ return dist > storm.radius;
452
+ }
453
+
454
+ // Storm damage application
455
+ let stormDamageAccumulator = 0;
456
+
457
+ function applyStormDamage(deltaTime) {
458
+ if (!stormActive) return;
459
+
460
+ if (playerInStorm()) {
461
+ // Damage increases as storm closes
462
+ const stormProgress = 1 - storm.radius / storm.maxRadius; // 0 to 1
463
+ const damageRate = storm.damagePerSecond * (1 + stormProgress * 4); // up to 5x damage
464
+ stormDamageAccumulator += damageRate * deltaTime;
465
+ while (stormDamageAccumulator >= 1) {
466
+ stormDamageAccumulator -= 1;
467
+ applyDamage(1);
468
  }
469
+ } else {
470
+ stormDamageAccumulator = 0;
471
+ }
472
+ }
473
+
474
+ // Apply damage to player health considering armor
475
+ function applyDamage(amount) {
476
+ if (playerArmor > 0) {
477
+ const armorAbsorb = Math.min(playerArmor, amount * 0.7); // Armor absorbs 70% of damage
478
+ playerArmor -= armorAbsorb;
479
+ amount -= armorAbsorb;
480
+ }
481
+ playerHealth -= amount;
482
+ if (playerHealth <= 0) {
483
+ playerHealth = 0;
484
+ playerDeath();
485
+ }
486
+ updatePlayerStats();
487
+ }
488
 
489
+ // Storm radius shrinking over time
490
+ function updateStorm(deltaTime) {
491
+ if (!stormActive) return;
492
+
493
+ storm.radius -= storm.closingSpeed * deltaTime;
494
+ if (storm.radius < 50) storm.radius = 50;
495
+ }
496
+
497
+ // Draw aim crosshair at mouse position
498
+ function drawCrosshair() {
499
+ ctx.save();
500
+ ctx.strokeStyle = 'yellow';
501
+ ctx.lineWidth = 2;
502
+ ctx.beginPath();
503
+ const size = 10;
504
+ ctx.moveTo(mouse.canvasX - size, mouse.canvasY);
505
+ ctx.lineTo(mouse.canvasX + size, mouse.canvasY);
506
+ ctx.moveTo(mouse.canvasX, mouse.canvasY - size);
507
+ ctx.lineTo(mouse.canvasX, mouse.canvasY + size);
508
+ ctx.stroke();
509
+ ctx.restore();
510
+ }
511
+
512
+ // Game timer and storm activation
513
+ let timerInterval;
514
+ function startGame() {
515
+ gameActive = true;
516
+ selectedBiome && console.log('Selected biome:', selectedBiome);
517
+ landingScreenEl.classList.add('hidden');
518
+ gameScreenEl.classList.remove('hidden');
519
+ stormWarningEl.classList.add('hidden');
520
+
521
+ // Reset stats
522
+ playerHealth = 100;
523
+ playerArmor = 0;
524
+ playerKills = 0;
525
+ updatePlayerStats();
526
+ initInventory();
527
+ initPlayerPosition();
528
+ storm.radius = storm.maxRadius;
529
+ stormActive = false;
530
+ stormWarningEl.classList.add('hidden');
531
+
532
+ gameTime = 300; // 5 minutes
533
+ document.getElementById('gameTimer').textContent = '5:00';
534
+
535
+ timerInterval && clearInterval(timerInterval);
536
+ timerInterval = setInterval(() => {
537
+ if (!gameActive) {
538
+ clearInterval(timerInterval);
539
+ return;
540
  }
541
+ gameTime--;
542
+ const minutes = Math.floor(gameTime / 60);
543
+ const seconds = gameTime % 60;
544
+ document.getElementById('gameTimer').textContent = `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
545
 
546
+ // Start storm after 60 seconds (4 minutes left)
547
+ if (gameTime === 240 && !stormActive) {
548
+ stormActive = true;
549
+ stormWarningEl.classList.remove('hidden');
550
+ setTimeout(() => stormWarningEl.classList.add('hidden'), 5000);
551
  }
552
 
553
+ // End game when timer hits 0
554
+ if (gameTime <= 0) {
555
+ clearInterval(timerInterval);
556
+ endGame();
 
 
 
 
 
 
 
557
  }
558
+ }, 1000);
559
+
560
+ lastFrameTime = performance.now();
561
+ requestAnimationFrame(gameLoop);
562
+ }
563
+
564
+ // End game
565
+ function endGame() {
566
+ gameActive = false;
567
+ alert('Congratulations! You survived the BattleZone!');
568
+ }
569
+
570
+ // Player death
571
+ function playerDeath() {
572
+ gameActive = false;
573
+ deathScreenEl.classList.remove('hidden');
574
+ }
575
+
576
+ // Respawn button handler
577
+ document.getElementById('respawnBtn').addEventListener('click', () => {
578
+ deathScreenEl.classList.add('hidden');
579
+ landingScreenEl.classList.remove('hidden');
580
+ });
581
+
582
+ // Biome selection handler
583
+ document.querySelectorAll('.biome-selector').forEach((selector) => {
584
+ selector.addEventListener('click', () => {
585
+ selectedBiome = selector.getAttribute('data-biome');
586
+ startGame();
587
+ });
588
+ });
589
+
590
+ // Game loop with delta time for smooth movement and storm update
591
+ let lastFrameTime = 0;
592
+ function gameLoop(timestamp) {
593
+ if (!gameActive) return;
594
+ if (!lastFrameTime) lastFrameTime = timestamp;
595
+ const deltaTime = (timestamp - lastFrameTime) / 1000; // seconds
596
+ lastFrameTime = timestamp;
597
+
598
+ // Update
599
+ movePlayer();
600
+ updateStorm(deltaTime);
601
+ applyStormDamage(deltaTime);
602
+
603
+ // Clear
604
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
605
+
606
+ // Draw
607
+ drawStorm();
608
+ drawPlayer();
609
+ drawCrosshair();
610
+
611
+ // Show storm warning if player is outside storm radius while storm active
612
+ if (stormActive && playerInStorm()) {
613
+ stormWarningEl.classList.remove('hidden');
614
+ } else {
615
+ stormWarningEl.classList.add('hidden');
616
+ }
617
+
618
+ requestAnimationFrame(gameLoop);
619
+ }
620
 
621
+ // Initialize feather icons and setup
622
+ feather.replace();
623
+ resizeCanvas();
624
+ initInventory();
625
+ updatePlayerStats();
626
+ </script>
627
  </body>
628
+ </html>