sagar007 commited on
Commit
c8d18e3
·
verified ·
1 Parent(s): bf26e4e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +328 -297
app.py CHANGED
@@ -1,7 +1,10 @@
1
  import gradio as gr
 
 
2
 
3
- # The HTML content of the bird shooter game
4
- html_content = """
 
5
  <!DOCTYPE html>
6
  <html>
7
  <head>
@@ -74,341 +77,369 @@ html_content = """
74
  </div>
75
 
76
  <script>
77
- const gameCanvas = document.getElementById('game-canvas');
78
- const scoreDisplay = document.getElementById('score');
79
- const gameOverDisplay = document.getElementById('game-over');
80
- const restartButton = document.getElementById('restart-button');
81
-
82
- let score = 0;
83
- let gameRunning = true;
84
- let birds = [];
85
- let explosions = [];
86
-
87
- // Create clouds in the background
88
- function createClouds() {
89
- const cloudCount = 5;
90
- for (let i = 0; i < cloudCount; i++) {
91
- const cloud = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
92
- cloud.setAttribute("cx", Math.random() * 800);
93
- cloud.setAttribute("cy", 50 + Math.random() * 100);
94
- cloud.setAttribute("rx", 50 + Math.random() * 50);
95
- cloud.setAttribute("ry", 20 + Math.random() * 20);
96
- cloud.setAttribute("fill", "white");
97
- cloud.setAttribute("opacity", "0.8");
98
- cloud.classList.add("cloud");
99
- gameCanvas.appendChild(cloud);
100
-
101
- // Create smaller ellipse attached to the cloud
102
- const cloudPart = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
103
- cloudPart.setAttribute("cx", parseFloat(cloud.getAttribute("cx")) + 30);
104
- cloudPart.setAttribute("cy", parseFloat(cloud.getAttribute("cy")) - 5);
105
- cloudPart.setAttribute("rx", 30);
106
- cloudPart.setAttribute("ry", 15);
107
- cloudPart.setAttribute("fill", "white");
108
- cloudPart.setAttribute("opacity", "0.8");
109
- gameCanvas.appendChild(cloudPart);
110
- }
111
- }
112
-
113
- // Bird class
114
- class Bird {
115
- constructor() {
116
- this.x = -50;
117
- this.y = 100 + Math.random() * 300;
118
- this.speed = 2 + Math.random() * 3;
119
- this.size = 30 + Math.random() * 20;
120
- this.element = this.createBirdElement();
121
- gameCanvas.appendChild(this.element);
122
  }
123
 
124
- createBirdElement() {
125
- const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
126
-
127
- // Bird body
128
- const body = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
129
- body.setAttribute("cx", "0");
130
- body.setAttribute("cy", "0");
131
- body.setAttribute("rx", this.size / 2);
132
- body.setAttribute("ry", this.size / 3);
133
- body.setAttribute("fill", this.getRandomColor());
134
- group.appendChild(body);
135
 
136
- // Bird head
137
- const head = document.createElementNS("http://www.w3.org/2000/svg", "circle");
138
- head.setAttribute("cx", this.size / 2);
139
- head.setAttribute("cy", -this.size / 6);
140
- head.setAttribute("r", this.size / 4);
141
- head.setAttribute("fill", this.getRandomColor());
142
- group.appendChild(head);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
- // Bird eye
145
- const eye = document.createElementNS("http://www.w3.org/2000/svg", "circle");
146
- eye.setAttribute("cx", this.size / 2 + this.size / 8);
147
- eye.setAttribute("cy", -this.size / 6 - this.size / 8);
148
- eye.setAttribute("r", this.size / 10);
149
- eye.setAttribute("fill", "black");
150
- group.appendChild(eye);
151
 
152
- // Bird beak
153
- const beak = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
154
- beak.setAttribute("points",
155
- `${this.size / 2 + this.size / 4},-${this.size / 6}
156
- ${this.size},0
157
- ${this.size / 2 + this.size / 4},${this.size / 10}`);
158
- beak.setAttribute("fill", "orange");
159
- group.appendChild(beak);
 
 
 
 
 
 
 
 
 
 
160
 
161
- // Bird wings
162
- const wing = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
163
- wing.setAttribute("cx", "0");
164
- wing.setAttribute("cy", this.size / 4);
165
- wing.setAttribute("rx", this.size / 3);
166
- wing.setAttribute("ry", this.size / 6);
167
- wing.setAttribute("fill", this.getRandomColor());
168
- wing.setAttribute("class", "wing");
169
- group.appendChild(wing);
170
 
171
- return group;
172
- }
173
-
174
- getRandomColor() {
175
- const colors = ["#FF5733", "#33FF57", "#3357FF", "#F3FF33", "#FF33F3", "#33FFF3"];
176
- return colors[Math.floor(Math.random() * colors.length)];
177
  }
178
 
179
- update() {
180
- this.x += this.speed;
181
- this.element.setAttribute("transform", `translate(${this.x}, ${this.y})`);
 
 
 
 
 
 
 
 
 
182
 
183
- // Animate wings
184
- const wing = this.element.querySelector(".wing");
185
- if (wing) {
186
- const wingAngle = 15 * Math.sin(Date.now() / 100);
187
- wing.setAttribute("transform", `rotate(${wingAngle})`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
 
190
- // Check if bird has left the screen
191
- if (this.x > 850) {
192
- this.remove();
193
- return false;
 
 
 
 
 
 
194
  }
195
- return true;
196
- }
197
-
198
- remove() {
199
- if (this.element.parentNode) {
200
- gameCanvas.removeChild(this.element);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  }
202
  }
203
 
204
- checkHit(x, y) {
205
- const birdX = this.x;
206
- const birdY = this.y;
207
- const distance = Math.sqrt(Math.pow(birdX - x, 2) + Math.pow(birdY - y, 2));
208
- return distance < this.size;
209
- }
210
- }
211
-
212
- // Explosion class
213
- class Explosion {
214
- constructor(x, y, size) {
215
- this.x = x;
216
- this.y = y;
217
- this.size = size;
218
- this.frame = 0;
219
- this.maxFrames = 20;
220
- this.element = this.createExplosionElement();
221
- gameCanvas.appendChild(this.element);
222
- this.playSound();
223
- }
224
-
225
- createExplosionElement() {
226
- const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
227
 
228
- // Create explosion particles
229
- const colors = ["#FF0000", "#FF7700", "#FFFF00"];
230
- const particleCount = 12;
 
 
231
 
232
- for (let i = 0; i < particleCount; i++) {
233
- const angle = (i / particleCount) * 2 * Math.PI;
234
- const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
235
- circle.setAttribute("cx", Math.cos(angle) * (this.size / 3));
236
- circle.setAttribute("cy", Math.sin(angle) * (this.size / 3));
237
- circle.setAttribute("r", this.size / 8);
238
- circle.setAttribute("fill", colors[Math.floor(Math.random() * colors.length)]);
239
- circle.setAttribute("class", "particle");
240
- circle.setAttribute("data-angle", angle);
241
- group.appendChild(circle);
242
  }
243
 
244
- // Add central explosion
245
- const center = document.createElementNS("http://www.w3.org/2000/svg", "circle");
246
- center.setAttribute("cx", 0);
247
- center.setAttribute("cy", 0);
248
- center.setAttribute("r", this.size / 2);
249
- center.setAttribute("fill", "#FF0000");
250
- center.setAttribute("class", "center");
251
- group.appendChild(center);
252
 
253
- group.setAttribute("transform", `translate(${this.x}, ${this.y})`);
254
- return group;
255
- }
256
-
257
- playSound() {
258
- // Create explosion sound
259
- const explosion = new Audio();
260
- explosion.src = "data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=";
261
- explosion.volume = 0.3;
262
- explosion.play();
263
  }
264
 
265
- update() {
266
- this.frame++;
267
-
268
- // Update explosion size and opacity
269
- const center = this.element.querySelector(".center");
270
- const sizeMultiplier = 1 + this.frame / 5;
271
- center.setAttribute("r", (this.size / 2) * sizeMultiplier);
272
- center.setAttribute("opacity", 1 - (this.frame / this.maxFrames));
273
 
274
- // Update particles
275
- const particles = this.element.querySelectorAll(".particle");
276
- particles.forEach(particle => {
277
- const angle = parseFloat(particle.getAttribute("data-angle"));
278
- const distance = (this.size / 3) + (this.frame * 2);
279
-
280
- const x = Math.cos(angle) * distance;
281
- const y = Math.sin(angle) * distance;
282
-
283
- particle.setAttribute("cx", x);
284
- particle.setAttribute("cy", y);
285
- particle.setAttribute("opacity", 1 - (this.frame / this.maxFrames));
286
- particle.setAttribute("r", this.size / 8 * (1 - this.frame / this.maxFrames));
287
- });
288
 
289
- // Check if explosion is finished
290
- if (this.frame >= this.maxFrames) {
291
- this.remove();
292
- return false;
 
293
  }
294
- return true;
295
- }
296
-
297
- remove() {
298
- if (this.element.parentNode) {
299
- gameCanvas.removeChild(this.element);
300
  }
301
- }
302
- }
303
-
304
- // Initialize the game
305
- function initGame() {
306
- score = 0;
307
- gameRunning = true;
308
- scoreDisplay.textContent = `Score: ${score}`;
309
- gameOverDisplay.style.display = 'none';
310
- restartButton.style.display = 'none';
311
-
312
- // Remove all birds and explosions
313
- birds.forEach(bird => bird.remove());
314
- explosions.forEach(explosion => explosion.remove());
315
- birds = [];
316
- explosions = [];
317
-
318
- // Clear any existing elements
319
- while (gameCanvas.firstChild) {
320
- gameCanvas.removeChild(gameCanvas.firstChild);
321
- }
322
-
323
- // Create clouds
324
- createClouds();
325
-
326
- // Start game loop
327
- gameLoop();
328
- }
329
-
330
- // Game loop
331
- function gameLoop() {
332
- if (!gameRunning) return;
333
-
334
- // Create new birds randomly
335
- if (Math.random() < 0.02) {
336
- birds.push(new Bird());
337
  }
338
 
339
- // Update birds
340
- for (let i = birds.length - 1; i >= 0; i--) {
341
- if (!birds[i].update()) {
342
- birds.splice(i, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  }
344
- }
345
-
346
- // Update explosions
347
- for (let i = explosions.length - 1; i >= 0; i--) {
348
- if (!explosions[i].update()) {
349
- explosions.splice(i, 1);
 
 
 
 
 
350
  }
351
- }
352
 
353
- requestAnimationFrame(gameLoop);
354
- }
355
-
356
- // Handle mouse clicks
357
- gameCanvas.addEventListener('click', (e) => {
358
- if (!gameRunning) return;
359
-
360
- const rect = gameCanvas.getBoundingClientRect();
361
- const x = e.clientX - rect.left;
362
- const y = e.clientY - rect.top;
363
 
364
- let hit = false;
365
-
366
- // Check if any bird was hit
367
- for (let i = birds.length - 1; i >= 0; i--) {
368
- if (birds[i].checkHit(x, y)) {
369
- // Create explosion
370
- const birdX = birds[i].x;
371
- const birdY = birds[i].y;
372
- const birdSize = birds[i].size;
373
-
374
- // Remove the bird
375
- birds[i].remove();
376
- birds.splice(i, 1);
377
-
378
- // Create explosion
379
- explosions.push(new Explosion(birdX, birdY, birdSize * 2));
380
-
381
- // Increment score
382
- score += 10;
383
- scoreDisplay.textContent = `Score: ${score}`;
384
-
385
- hit = true;
386
- }
387
- }
388
-
389
- // Play miss sound if no bird was hit
390
- if (!hit) {
391
- const miss = new Audio();
392
- miss.src = "data:audio/wav;base64,UklGRiQDAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YQADAABkAGQAZABkAGQAfACEAJwAsAC8AMgA1ADsAOQA7ADkANQA0AC8AKgAnACMAHQAXABMAEQAPABEADwANAA0ADQALAAsACQAHAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA8AFgAaAB8AIQAnACsAMAAyADMANwA3ADcAMgA0ADAALAApACQAIQAbABYAEQAMAAUAAAAAAAAAAAAAAAAAAAAAAAAAAP//9//x//X/9f/4/wAABwANABYAHAAnADIAOABDAEsAVABdAGQAbQBzAH4AhQCKAJEAlQCYAJ4AnwCgAKIAoQCgAJwAmgCXAJIAjwCIAIMAfQB2AG4AZgBeAFQATABGAD4ANQAvACgAIgAaABUADAAIAAQAAQD+//r/9//0//H/7//u/+z/6//r/+r/6v/p/+n/6v/q/+v/7P/u/+//8f/z//X/+P/7//7/AQADAAYACQALABAAEQAUABYAGAAZAB0AHQAfACEAIgAkACUAJQAmACcAJwAoACkAKQAqACsAKwAsACwALQAtAC0ALQAuAC4ALgAuAC4ALgAtAC0ALQAsACwALAAqACkAKQAnACYAJgAkACMAIgAgAB8AHgAcABoAGQAYABYAFAAQAA4ADAAJAAcABQADAAEA//89//7//f/8//v/+v/5//j/9//2//X/9P/z//P/8v/x//D/8P/v/+7/7v/t/+3/7P/s/+v/6//q/+r/6v/p/+n/6f/p/+n/6f/p/+n/6f/p/+n/6v/q/+v/6//s/+z/7f/u/+7/7//w//H/8v/z//T/9f/2//f/+P/5//v//P/9/wAAAgADAAUABgAIAAkACwAMAA4AEAARACMACwAEAP//+//4//X/8v/v/+v/6P/l/+L/4P/e/9v/2f/X/9X/1P/S/9H/z//O/83/zf/M/8v/y//K/8r/yv/K/8v/y//L/8z/zf/O/8//0P/S/9P/1f/X/9j/2v/c/97/4f/j/+X/6P/q/+3/8P/z//X/+P/7//7/AQA=";
393
- miss.volume = 0.2;
394
- miss.play();
395
- }
396
- });
397
-
398
- // Restart game when button is clicked
399
- restartButton.addEventListener('click', () => {
400
  initGame();
401
- });
402
-
403
- // Initialize the game
404
- initGame();
405
  </script>
406
  </body>
407
  </html>
408
  """
 
 
 
 
 
 
 
 
 
 
409
 
410
  def create_game():
411
- return gr.HTML(html_content)
 
 
412
 
413
  # Create Gradio interface
414
  with gr.Blocks(title="Bird Shooter Game") as demo:
 
1
  import gradio as gr
2
+ import tempfile
3
+ import os
4
 
5
+ # Create a temporary HTML file with the game
6
+ def create_game_html():
7
+ html_content = """
8
  <!DOCTYPE html>
9
  <html>
10
  <head>
 
77
  </div>
78
 
79
  <script>
80
+ // Wait for window to fully load before initializing game
81
+ window.onload = function() {
82
+ const gameCanvas = document.getElementById('game-canvas');
83
+ const scoreDisplay = document.getElementById('score');
84
+ const gameOverDisplay = document.getElementById('game-over');
85
+ const restartButton = document.getElementById('restart-button');
86
+
87
+ let score = 0;
88
+ let gameRunning = true;
89
+ let birds = [];
90
+ let explosions = [];
91
+
92
+ // Create clouds in the background
93
+ function createClouds() {
94
+ const cloudCount = 5;
95
+ for (let i = 0; i < cloudCount; i++) {
96
+ const cloud = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
97
+ cloud.setAttribute("cx", Math.random() * 800);
98
+ cloud.setAttribute("cy", 50 + Math.random() * 100);
99
+ cloud.setAttribute("rx", 50 + Math.random() * 50);
100
+ cloud.setAttribute("ry", 20 + Math.random() * 20);
101
+ cloud.setAttribute("fill", "white");
102
+ cloud.setAttribute("opacity", "0.8");
103
+ cloud.classList.add("cloud");
104
+ gameCanvas.appendChild(cloud);
105
+
106
+ // Create smaller ellipse attached to the cloud
107
+ const cloudPart = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
108
+ cloudPart.setAttribute("cx", parseFloat(cloud.getAttribute("cx")) + 30);
109
+ cloudPart.setAttribute("cy", parseFloat(cloud.getAttribute("cy")) - 5);
110
+ cloudPart.setAttribute("rx", 30);
111
+ cloudPart.setAttribute("ry", 15);
112
+ cloudPart.setAttribute("fill", "white");
113
+ cloudPart.setAttribute("opacity", "0.8");
114
+ gameCanvas.appendChild(cloudPart);
115
+ }
 
 
 
 
 
 
 
 
 
116
  }
117
 
118
+ // Bird class
119
+ class Bird {
120
+ constructor() {
121
+ this.x = -50;
122
+ this.y = 100 + Math.random() * 300;
123
+ this.speed = 2 + Math.random() * 3;
124
+ this.size = 30 + Math.random() * 20;
125
+ this.element = this.createBirdElement();
126
+ gameCanvas.appendChild(this.element);
127
+ }
 
128
 
129
+ createBirdElement() {
130
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
131
+
132
+ // Bird body
133
+ const body = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
134
+ body.setAttribute("cx", "0");
135
+ body.setAttribute("cy", "0");
136
+ body.setAttribute("rx", this.size / 2);
137
+ body.setAttribute("ry", this.size / 3);
138
+ body.setAttribute("fill", this.getRandomColor());
139
+ group.appendChild(body);
140
+
141
+ // Bird head
142
+ const head = document.createElementNS("http://www.w3.org/2000/svg", "circle");
143
+ head.setAttribute("cx", this.size / 2);
144
+ head.setAttribute("cy", -this.size / 6);
145
+ head.setAttribute("r", this.size / 4);
146
+ head.setAttribute("fill", this.getRandomColor());
147
+ group.appendChild(head);
148
+
149
+ // Bird eye
150
+ const eye = document.createElementNS("http://www.w3.org/2000/svg", "circle");
151
+ eye.setAttribute("cx", this.size / 2 + this.size / 8);
152
+ eye.setAttribute("cy", -this.size / 6 - this.size / 8);
153
+ eye.setAttribute("r", this.size / 10);
154
+ eye.setAttribute("fill", "black");
155
+ group.appendChild(eye);
156
+
157
+ // Bird beak
158
+ const beak = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
159
+ beak.setAttribute("points",
160
+ `${this.size / 2 + this.size / 4},-${this.size / 6}
161
+ ${this.size},0
162
+ ${this.size / 2 + this.size / 4},${this.size / 10}`);
163
+ beak.setAttribute("fill", "orange");
164
+ group.appendChild(beak);
165
+
166
+ // Bird wings
167
+ const wing = document.createElementNS("http://www.w3.org/2000/svg", "ellipse");
168
+ wing.setAttribute("cx", "0");
169
+ wing.setAttribute("cy", this.size / 4);
170
+ wing.setAttribute("rx", this.size / 3);
171
+ wing.setAttribute("ry", this.size / 6);
172
+ wing.setAttribute("fill", this.getRandomColor());
173
+ wing.setAttribute("class", "wing");
174
+ group.appendChild(wing);
175
+
176
+ return group;
177
+ }
178
 
179
+ getRandomColor() {
180
+ const colors = ["#FF5733", "#33FF57", "#3357FF", "#F3FF33", "#FF33F3", "#33FFF3"];
181
+ return colors[Math.floor(Math.random() * colors.length)];
182
+ }
 
 
 
183
 
184
+ update() {
185
+ this.x += this.speed;
186
+ this.element.setAttribute("transform", `translate(${this.x}, ${this.y})`);
187
+
188
+ // Animate wings
189
+ const wing = this.element.querySelector(".wing");
190
+ if (wing) {
191
+ const wingAngle = 15 * Math.sin(Date.now() / 100);
192
+ wing.setAttribute("transform", `rotate(${wingAngle})`);
193
+ }
194
+
195
+ // Check if bird has left the screen
196
+ if (this.x > 850) {
197
+ this.remove();
198
+ return false;
199
+ }
200
+ return true;
201
+ }
202
 
203
+ remove() {
204
+ if (this.element.parentNode) {
205
+ gameCanvas.removeChild(this.element);
206
+ }
207
+ }
 
 
 
 
208
 
209
+ checkHit(x, y) {
210
+ const birdX = this.x;
211
+ const birdY = this.y;
212
+ const distance = Math.sqrt(Math.pow(birdX - x, 2) + Math.pow(birdY - y, 2));
213
+ return distance < this.size;
214
+ }
215
  }
216
 
217
+ // Explosion class
218
+ class Explosion {
219
+ constructor(x, y, size) {
220
+ this.x = x;
221
+ this.y = y;
222
+ this.size = size;
223
+ this.frame = 0;
224
+ this.maxFrames = 20;
225
+ this.element = this.createExplosionElement();
226
+ gameCanvas.appendChild(this.element);
227
+ this.playSound();
228
+ }
229
 
230
+ createExplosionElement() {
231
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
232
+
233
+ // Create explosion particles
234
+ const colors = ["#FF0000", "#FF7700", "#FFFF00"];
235
+ const particleCount = 12;
236
+
237
+ for (let i = 0; i < particleCount; i++) {
238
+ const angle = (i / particleCount) * 2 * Math.PI;
239
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
240
+ circle.setAttribute("cx", Math.cos(angle) * (this.size / 3));
241
+ circle.setAttribute("cy", Math.sin(angle) * (this.size / 3));
242
+ circle.setAttribute("r", this.size / 8);
243
+ circle.setAttribute("fill", colors[Math.floor(Math.random() * colors.length)]);
244
+ circle.setAttribute("class", "particle");
245
+ circle.setAttribute("data-angle", angle);
246
+ group.appendChild(circle);
247
+ }
248
+
249
+ // Add central explosion
250
+ const center = document.createElementNS("http://www.w3.org/2000/svg", "circle");
251
+ center.setAttribute("cx", 0);
252
+ center.setAttribute("cy", 0);
253
+ center.setAttribute("r", this.size / 2);
254
+ center.setAttribute("fill", "#FF0000");
255
+ center.setAttribute("class", "center");
256
+ group.appendChild(center);
257
+
258
+ group.setAttribute("transform", `translate(${this.x}, ${this.y})`);
259
+ return group;
260
  }
261
 
262
+ playSound() {
263
+ try {
264
+ // Create explosion sound
265
+ const explosion = new Audio();
266
+ explosion.src = "data:audio/wav;base64,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qJrx4KOQjahZxWbcZgztj2c49nKmkId44S71j0c8eV9yDK6uPRzx5X18eDvjvQ6yKo9ZSS6l//8elePK/Lf//IInrOF/FvDoADYAGBMGb7FtErm5MXMlmPAJQVgWta7Zx2go+8xJ0UiCb8LHHdftWyLJE0QIAIsI+UbXu67dZMjmgDGCGl1H+vpF4NSDckSIkk7Vd+sxEhBQMRU8j/12UIRhzSaUdQ+rQU5kGeFxm+hb1oh6pWWmv3uvmReDl0UnvtapVaIzo1jZbf/pD6ElLqSX+rUmOQNpJFa/r+sa4e/pBlAABoAAAAA3CUgShLdGIxsY7AUABPRrgCABdDuQ5GC7DqPQCgbbJUAoRSUj+NIEig0YfyWUho1VBBBA//uQZB4ABZx5zfMakeAAAAmwAAAAF5F3P0w9GtAAACfAAAAAwLhMDmAYWMgVEG1U0FIGCBgXBXAtfMH10000EEEEEECUBYln03TTTdNBDZopopYvrTTdNa325mImNg3TTPV9q3pmY0xoO6bv3r00y+IDGid/9aaaZTGMuj9mpu9Mpio1dXrr5HERTZSmqU36A3CumzN/9Robv/Xx4v9ijkSRSNLQhAWumap82WRSBUqXStV/YcS+XVLnSS+WLDroqArFkMEsAS+eWmrUzrO0oEmE40RlMZ5+ODIkAyKAGUwZ3mVKmcamcJnMW26MRPgUw6j+LkhyHGVGYjSUUKNpuJUQoOIAyDvEyG8S5yfK6dhZc0Tx1KI/gviKL6qvvFs1+bWtaz58uUNnryq6kt5RzOCkPWlVqVX2a/EEBUdU1KrXLf40GoiiFXK///qpoiDXrOgqDR38JB0bw7SoL+ZB9o1RCkQjQ2CBYZKd/+VJxZRRZlqSkKiws0WFxUyCwsKiMy7hUVFhIaCrNQsKkTIsLivwKKigsj8XYlwt/WKi2N4d//uQRCSAAjURNIHpMZBGYiaQPSYyAAABLAAAAAAAACWAAAAApUF/Mg+0aohSIRobBAsMlO//Kk4soosy1JSFRYWaLC4qZBYWFRGZdwqKiwkNBVmoWFSJkWFxX4FFRQWR+LsS4W/rFRb/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VEFHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU291bmRib3kuZGUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMjAwNGh0dHA6Ly93d3cuc291bmRib3kuZGUAAAAAAAAAACU=";
267
+ explosion.volume = 0.3;
268
+ explosion.play();
269
+ } catch (e) {
270
+ console.log("Sound error:", e);
271
+ }
272
  }
273
+
274
+ update() {
275
+ this.frame++;
276
+
277
+ // Update explosion size and opacity
278
+ const center = this.element.querySelector(".center");
279
+ const sizeMultiplier = 1 + this.frame / 5;
280
+ center.setAttribute("r", (this.size / 2) * sizeMultiplier);
281
+ center.setAttribute("opacity", 1 - (this.frame / this.maxFrames));
282
+
283
+ // Update particles
284
+ const particles = this.element.querySelectorAll(".particle");
285
+ particles.forEach(particle => {
286
+ const angle = parseFloat(particle.getAttribute("data-angle"));
287
+ const distance = (this.size / 3) + (this.frame * 2);
288
+
289
+ const x = Math.cos(angle) * distance;
290
+ const y = Math.sin(angle) * distance;
291
+
292
+ particle.setAttribute("cx", x);
293
+ particle.setAttribute("cy", y);
294
+ particle.setAttribute("opacity", 1 - (this.frame / this.maxFrames));
295
+ particle.setAttribute("r", this.size / 8 * (1 - this.frame / this.maxFrames));
296
+ });
297
+
298
+ // Check if explosion is finished
299
+ if (this.frame >= this.maxFrames) {
300
+ this.remove();
301
+ return false;
302
+ }
303
+ return true;
304
+ }
305
+
306
+ remove() {
307
+ if (this.element.parentNode) {
308
+ gameCanvas.removeChild(this.element);
309
+ }
310
  }
311
  }
312
 
313
+ // Initialize the game
314
+ function initGame() {
315
+ console.log("Initializing game...");
316
+ score = 0;
317
+ gameRunning = true;
318
+ scoreDisplay.textContent = `Score: ${score}`;
319
+ gameOverDisplay.style.display = 'none';
320
+ restartButton.style.display = 'none';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
 
322
+ // Remove all birds and explosions
323
+ birds.forEach(bird => bird.remove());
324
+ explosions.forEach(explosion => explosion.remove());
325
+ birds = [];
326
+ explosions = [];
327
 
328
+ // Clear any existing elements
329
+ while (gameCanvas.firstChild) {
330
+ gameCanvas.removeChild(gameCanvas.firstChild);
 
 
 
 
 
 
 
331
  }
332
 
333
+ // Create clouds
334
+ createClouds();
 
 
 
 
 
 
335
 
336
+ // Immediately create first bird to make sure something appears
337
+ birds.push(new Bird());
338
+
339
+ // Start game loop
340
+ gameLoop();
341
+ console.log("Game loop started");
 
 
 
 
342
  }
343
 
344
+ // Game loop
345
+ function gameLoop() {
346
+ if (!gameRunning) return;
 
 
 
 
 
347
 
348
+ // Create new birds randomly
349
+ if (Math.random() < 0.02) {
350
+ birds.push(new Bird());
351
+ }
 
 
 
 
 
 
 
 
 
 
352
 
353
+ // Update birds
354
+ for (let i = birds.length - 1; i >= 0; i--) {
355
+ if (!birds[i].update()) {
356
+ birds.splice(i, 1);
357
+ }
358
  }
359
+
360
+ // Update explosions
361
+ for (let i = explosions.length - 1; i >= 0; i--) {
362
+ if (!explosions[i].update()) {
363
+ explosions.splice(i, 1);
364
+ }
365
  }
366
+
367
+ requestAnimationFrame(gameLoop);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  }
369
 
370
+ // Handle mouse clicks
371
+ gameCanvas.addEventListener('click', (e) => {
372
+ if (!gameRunning) return;
373
+
374
+ const rect = gameCanvas.getBoundingClientRect();
375
+ const x = e.clientX - rect.left;
376
+ const y = e.clientY - rect.top;
377
+
378
+ let hit = false;
379
+
380
+ // Check if any bird was hit
381
+ for (let i = birds.length - 1; i >= 0; i--) {
382
+ if (birds[i].checkHit(x, y)) {
383
+ // Create explosion
384
+ const birdX = birds[i].x;
385
+ const birdY = birds[i].y;
386
+ const birdSize = birds[i].size;
387
+
388
+ // Remove the bird
389
+ birds[i].remove();
390
+ birds.splice(i, 1);
391
+
392
+ // Create explosion
393
+ explosions.push(new Explosion(birdX, birdY, birdSize * 2));
394
+
395
+ // Increment score
396
+ score += 10;
397
+ scoreDisplay.textContent = `Score: ${score}`;
398
+
399
+ hit = true;
400
+ }
401
  }
402
+
403
+ // Play miss sound if no bird was hit
404
+ if (!hit) {
405
+ try {
406
+ const miss = new Audio();
407
+ miss.src = "data:audio/wav;base64,UklGRiQDAABXQVZFZm10IBAAAAABAAEAESsAABErAAABAAgAZGF0YQADAABkAGQAZABkAGQAfACEAJwAsAC8AMgA1ADsAOQA7ADkANQA0AC8AKgAnACMAHQAXABMAEQAPABEADwANAA0ADQALAAsACQAHAAUAAwABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAA8AFgAaAB8AIQAnACsAMAAyADMANwA3ADcAMgA0ADAALAApACQAIQAbABYAEQAMAAUAAAAAAAAAAAAAAAAAAAAAAAAAAP//9//x//X/9f/4/wAABwANABYAHAAnADIAOABDAEsAVABdAGQAbQBzAH4AhQCKAJEAlQCYAJ4AnwCgAKIAoQCgAJwAmgCXAJIAjwCIAIMAfQB2AG4AZgBeAFQATABGAD4ANQAvACgAIgAaABUADAAIAAQAAQD+//r/9//0//H/7//u/+z/6//r/+r/6v/p/+n/6v/q/+v/7P/u/+//8f/z//X/+P/7//7/AQADAAYACQALABAAEQAUABYAGAAZAB0AHQAfACEAIgAkACUAJQAmACcAJwAoACkAKQAqACsAKwAsACwALQAtAC0ALQAuAC4ALgAuAC4ALgAtAC0ALQAsACwALAAqACkAKQAnACYAJgAkACMAIgAgAB8AHgAcABoAGQAYABYAFAAQAA4ADAAJAAcABQADAAEA//89//7//f/8//v/+v/5//j/9//2//X/9P/z//P/8v/x//D/8P/v/+7/7v/t/+3/7P/s/+v/6//q/+r/6v/p/+n/6f/p/+n/6f/p/+n/6f/p/+n/6v/q/+v/6//s/+z/7f/u/+7/7//w//H/8v/z//T/9f/2//f/+P/5//v//P/9/wAAAgADAAUABgAIAAkACwAMAA4AEAARACMACwAEAP//+//4//X/8v/v/+v/6P/l/+L/4P/e/9v/2f/X/9X/1P/S/9H/z//O/83/zf/M/8v/y//K/8r/yv/K/8v/y//L/8z/zf/O/8//0P/S/9P/1f/X/9j/2v/c/97/4f/j/+X/6P/q/+3/8P/z//X/+P/7//7/AQA=";
408
+ miss.volume = 0.2;
409
+ miss.play();
410
+ } catch (e) {
411
+ console.log("Sound error:", e);
412
+ }
413
  }
414
+ });
415
 
416
+ // Restart game when button is clicked
417
+ restartButton.addEventListener('click', () => {
418
+ initGame();
419
+ });
 
 
 
 
 
 
420
 
421
+ // Initialize the game
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
  initGame();
423
+ };
 
 
 
424
  </script>
425
  </body>
426
  </html>
427
  """
428
+
429
+ # Create a temporary file to serve the HTML
430
+ temp_dir = tempfile.mkdtemp()
431
+ html_path = os.path.join(temp_dir, "game.html")
432
+
433
+ with open(html_path, "w") as f:
434
+ f.write(html_content)
435
+
436
+ # Return the path to be used in the iframe
437
+ return html_path
438
 
439
  def create_game():
440
+ html_path = create_game_html()
441
+ iframe_html = f'<iframe src="file://{html_path}" width="820" height="650" frameborder="0"></iframe>'
442
+ return gr.HTML(iframe_html)
443
 
444
  # Create Gradio interface
445
  with gr.Blocks(title="Bird Shooter Game") as demo: