Remsky commited on
Commit
028af9f
·
verified ·
1 Parent(s): 959ad09

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +698 -18
index.html CHANGED
@@ -1,19 +1,699 @@
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>Quantum Flipper - The Backflipping Bird</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
+ @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
11
+
12
+ body {
13
+ margin: 0;
14
+ padding: 0;
15
+ overflow: hidden;
16
+ font-family: 'Press Start 2P', cursive;
17
+ background-color: #0f0f1a;
18
+ color: #e0e0ff;
19
+ }
20
+
21
+ #gameCanvas {
22
+ display: block;
23
+ background: linear-gradient(135deg, #000428, #004e92);
24
+ }
25
+
26
+ .universe-portal {
27
+ position: absolute;
28
+ width: 100px;
29
+ height: 100px;
30
+ border-radius: 50%;
31
+ background: radial-gradient(circle, rgba(0,255,255,0.8) 0%, rgba(0,0,255,0) 70%);
32
+ box-shadow: 0 0 30px cyan;
33
+ animation: pulse 2s infinite alternate;
34
+ z-index: 10;
35
+ }
36
+
37
+ @keyframes pulse {
38
+ 0% { transform: scale(1); opacity: 0.8; }
39
+ 100% { transform: scale(1.2); opacity: 1; }
40
+ }
41
+
42
+ .streak-effect {
43
+ position: absolute;
44
+ width: 100%;
45
+ height: 100%;
46
+ background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
47
+ pointer-events: none;
48
+ z-index: 5;
49
+ }
50
+
51
+ .turtle {
52
+ position: absolute;
53
+ width: 40px;
54
+ height: 30px;
55
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 80"><path fill="%234CAF50" d="M20,40 Q50,10 80,40 Q50,70 20,40 Z"/><circle cx="35" cy="35" r="5" fill="black"/><circle cx="65" cy="35" r="5" fill="black"/></svg>');
56
+ background-size: contain;
57
+ background-repeat: no-repeat;
58
+ z-index: 2;
59
+ }
60
+
61
+ .bird {
62
+ position: absolute;
63
+ width: 50px;
64
+ height: 40px;
65
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 80"><path fill="%23FF5722" d="M10,40 L40,20 L90,40 L40,60 Z"/><circle cx="70" cy="40" r="10" fill="%23FF9800"/><circle cx="75" cy="35" r="3" fill="white"/><circle cx="75" cy="35" r="1" fill="black"/></svg>');
66
+ background-size: contain;
67
+ background-repeat: no-repeat;
68
+ z-index: 3;
69
+ transition: transform 0.2s ease;
70
+ }
71
+
72
+ .flipping {
73
+ animation: backflip 0.5s linear;
74
+ }
75
+
76
+ @keyframes backflip {
77
+ 0% { transform: rotateY(0deg); }
78
+ 100% { transform: rotateY(360deg); }
79
+ }
80
+
81
+ .game-ui {
82
+ position: absolute;
83
+ top: 20px;
84
+ left: 20px;
85
+ z-index: 100;
86
+ }
87
+
88
+ .universe-indicator {
89
+ position: absolute;
90
+ bottom: 20px;
91
+ right: 20px;
92
+ font-size: 14px;
93
+ background: rgba(0,0,0,0.7);
94
+ padding: 10px;
95
+ border-radius: 10px;
96
+ border: 2px solid cyan;
97
+ }
98
+
99
+ .streak-counter {
100
+ position: absolute;
101
+ top: 20px;
102
+ right: 20px;
103
+ font-size: 18px;
104
+ color: gold;
105
+ text-shadow: 0 0 5px rgba(255,215,0,0.7);
106
+ }
107
+
108
+ .game-over {
109
+ position: absolute;
110
+ top: 0;
111
+ left: 0;
112
+ width: 100%;
113
+ height: 100%;
114
+ background: rgba(0,0,0,0.8);
115
+ display: flex;
116
+ flex-direction: column;
117
+ justify-content: center;
118
+ align-items: center;
119
+ z-index: 200;
120
+ }
121
+
122
+ .start-screen {
123
+ position: absolute;
124
+ top: 0;
125
+ left: 0;
126
+ width: 100%;
127
+ height: 100%;
128
+ background: linear-gradient(135deg, #000428, #004e92);
129
+ display: flex;
130
+ flex-direction: column;
131
+ justify-content: center;
132
+ align-items: center;
133
+ z-index: 300;
134
+ }
135
+
136
+ .title {
137
+ font-size: 3rem;
138
+ color: #FF5722;
139
+ text-shadow: 0 0 10px rgba(255,87,34,0.7);
140
+ margin-bottom: 2rem;
141
+ animation: glow 1.5s infinite alternate;
142
+ }
143
+
144
+ @keyframes glow {
145
+ from { text-shadow: 0 0 5px #FF5722; }
146
+ to { text-shadow: 0 0 20px #FF9800, 0 0 30px #FF5722; }
147
+ }
148
+
149
+ .instructions {
150
+ background: rgba(0,0,0,0.7);
151
+ padding: 20px;
152
+ border-radius: 10px;
153
+ margin-bottom: 2rem;
154
+ max-width: 500px;
155
+ text-align: center;
156
+ line-height: 1.6;
157
+ }
158
+
159
+ .btn {
160
+ background: linear-gradient(135deg, #FF5722, #FF9800);
161
+ border: none;
162
+ color: white;
163
+ padding: 15px 30px;
164
+ font-size: 1.2rem;
165
+ border-radius: 50px;
166
+ cursor: pointer;
167
+ font-family: 'Press Start 2P', cursive;
168
+ transition: all 0.3s;
169
+ box-shadow: 0 5px 15px rgba(0,0,0,0.3);
170
+ }
171
+
172
+ .btn:hover {
173
+ transform: translateY(-3px);
174
+ box-shadow: 0 8px 20px rgba(0,0,0,0.4);
175
+ }
176
+
177
+ .btn:active {
178
+ transform: translateY(1px);
179
+ }
180
+
181
+ .particle {
182
+ position: absolute;
183
+ width: 5px;
184
+ height: 5px;
185
+ background-color: cyan;
186
+ border-radius: 50%;
187
+ pointer-events: none;
188
+ z-index: 1;
189
+ }
190
+ </style>
191
+ </head>
192
+ <body>
193
+ <canvas id="gameCanvas"></canvas>
194
+
195
+ <div class="game-ui">
196
+ <div id="score" class="text-white text-xl">Score: 0</div>
197
+ </div>
198
+
199
+ <div id="streakCounter" class="streak-counter hidden">Streak: 0</div>
200
+ <div id="universeIndicator" class="universe-indicator hidden">Universe: 1</div>
201
+
202
+ <div id="startScreen" class="start-screen">
203
+ <h1 class="title">QUANTUM FLIPPER</h1>
204
+ <div class="instructions">
205
+ <p>Control the quantum bird with arrow keys</p>
206
+ <p>Press SPACE to backflip</p>
207
+ <p>3 backflips in a row opens a portal to a parallel universe</p>
208
+ <p>Avoid the turtles - they'll break your streak!</p>
209
+ </div>
210
+ <button id="startBtn" class="btn">START ADVENTURE</button>
211
+ </div>
212
+
213
+ <div id="gameOverScreen" class="game-over hidden">
214
+ <h1 class="title">GAME OVER</h1>
215
+ <div id="finalScore" class="text-white text-2xl mb-8">Score: 0</div>
216
+ <div id="universesVisited" class="text-cyan-300 text-xl mb-8">Universes Visited: 0</div>
217
+ <button id="restartBtn" class="btn">FLIP AGAIN</button>
218
+ </div>
219
+
220
+ <script>
221
+ // Game variables
222
+ const canvas = document.getElementById('gameCanvas');
223
+ const ctx = canvas.getContext('2d');
224
+ const startScreen = document.getElementById('startScreen');
225
+ const gameOverScreen = document.getElementById('gameOverScreen');
226
+ const startBtn = document.getElementById('startBtn');
227
+ const restartBtn = document.getElementById('restartBtn');
228
+ const scoreDisplay = document.getElementById('score');
229
+ const finalScoreDisplay = document.getElementById('finalScore');
230
+ const universesVisitedDisplay = document.getElementById('universesVisited');
231
+ const streakCounter = document.getElementById('streakCounter');
232
+ const universeIndicator = document.getElementById('universeIndicator');
233
+
234
+ // Set canvas size
235
+ canvas.width = window.innerWidth;
236
+ canvas.height = window.innerHeight;
237
+
238
+ // Game state
239
+ let gameRunning = false;
240
+ let score = 0;
241
+ let streak = 0;
242
+ let universe = 1;
243
+ let bird = {
244
+ x: 100,
245
+ y: 100,
246
+ width: 50,
247
+ height: 40,
248
+ speed: 5,
249
+ isFlipping: false
250
+ };
251
+
252
+ let turtles = [];
253
+ let portals = [];
254
+ let particles = [];
255
+ let keys = {};
256
+ let lastFlipTime = 0;
257
+ let flipCooldown = 500; // milliseconds
258
+ let gameLoopInterval;
259
+ let turtleSpawnInterval;
260
+ let backgroundHue = 200;
261
+
262
+ // Event listeners
263
+ window.addEventListener('keydown', (e) => {
264
+ keys[e.key] = true;
265
+
266
+ if (e.key === ' ' && gameRunning && !bird.isFlipping && Date.now() - lastFlipTime > flipCooldown) {
267
+ performBackflip();
268
+ }
269
+ });
270
+
271
+ window.addEventListener('keyup', (e) => {
272
+ keys[e.key] = false;
273
+ });
274
+
275
+ startBtn.addEventListener('click', startGame);
276
+ restartBtn.addEventListener('click', startGame);
277
+
278
+ window.addEventListener('resize', () => {
279
+ canvas.width = window.innerWidth;
280
+ canvas.height = window.innerHeight;
281
+ });
282
+
283
+ function startGame() {
284
+ // Reset game state
285
+ gameRunning = true;
286
+ score = 0;
287
+ streak = 0;
288
+ universe = 1;
289
+ bird.x = 100;
290
+ bird.y = 100;
291
+ turtles = [];
292
+ portals = [];
293
+ particles = [];
294
+
295
+ // Update UI
296
+ scoreDisplay.textContent = `Score: ${score}`;
297
+ streakCounter.classList.add('hidden');
298
+ universeIndicator.textContent = `Universe: ${universe}`;
299
+ universeIndicator.classList.remove('hidden');
300
+
301
+ // Hide screens
302
+ startScreen.classList.add('hidden');
303
+ gameOverScreen.classList.add('hidden');
304
+
305
+ // Start game loops
306
+ clearInterval(gameLoopInterval);
307
+ clearInterval(turtleSpawnInterval);
308
+
309
+ gameLoopInterval = setInterval(gameLoop, 16);
310
+ turtleSpawnInterval = setInterval(spawnTurtle, 2000);
311
+ }
312
+
313
+ function gameLoop() {
314
+ update();
315
+ render();
316
+ }
317
+
318
+ function update() {
319
+ // Move bird based on key presses
320
+ if (keys['ArrowUp'] && bird.y > 0) {
321
+ bird.y -= bird.speed;
322
+ }
323
+ if (keys['ArrowDown'] && bird.y < canvas.height - bird.height) {
324
+ bird.y += bird.speed;
325
+ }
326
+ if (keys['ArrowLeft'] && bird.x > 0) {
327
+ bird.x -= bird.speed;
328
+ }
329
+ if (keys['ArrowRight'] && bird.x < canvas.width - bird.width) {
330
+ bird.x += bird.speed;
331
+ }
332
+
333
+ // Update turtles
334
+ turtles.forEach((turtle, index) => {
335
+ turtle.x += turtle.speedX;
336
+ turtle.y += turtle.speedY;
337
+
338
+ // Bounce off walls
339
+ if (turtle.x <= 0 || turtle.x >= canvas.width - turtle.width) {
340
+ turtle.speedX *= -1;
341
+ }
342
+ if (turtle.y <= 0 || turtle.y >= canvas.height - turtle.height) {
343
+ turtle.speedY *= -1;
344
+ }
345
+
346
+ // Check collision with bird
347
+ if (
348
+ bird.x < turtle.x + turtle.width &&
349
+ bird.x + bird.width > turtle.x &&
350
+ bird.y < turtle.y + turtle.height &&
351
+ bird.y + bird.height > turtle.y
352
+ ) {
353
+ // If bird is flipping, turtle is destroyed
354
+ if (bird.isFlipping) {
355
+ turtles.splice(index, 1);
356
+ score += 50;
357
+ createParticles(turtle.x + turtle.width/2, turtle.y + turtle.height/2, 10, 'lime');
358
+ } else {
359
+ // Otherwise, streak is broken
360
+ if (streak > 0) {
361
+ streak = 0;
362
+ streakCounter.textContent = `Streak: ${streak}`;
363
+ streakCounter.classList.add('hidden');
364
+ createParticles(bird.x + bird.width/2, bird.y + bird.height/2, 15, 'red');
365
+ }
366
+ }
367
+ }
368
+ });
369
+
370
+ // Update particles
371
+ particles.forEach((particle, index) => {
372
+ particle.x += particle.speedX;
373
+ particle.y += particle.speedY;
374
+ particle.lifetime--;
375
+
376
+ if (particle.lifetime <= 0) {
377
+ particles.splice(index, 1);
378
+ }
379
+ });
380
+
381
+ // Update score display
382
+ scoreDisplay.textContent = `Score: ${score}`;
383
+ }
384
+
385
+ function render() {
386
+ // Clear canvas
387
+ ctx.fillStyle = `hsl(${backgroundHue}, 80%, 10%)`;
388
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
389
+
390
+ // Draw stars
391
+ drawStars();
392
+
393
+ // Draw portals
394
+ portals.forEach(portal => {
395
+ ctx.beginPath();
396
+ ctx.arc(portal.x, portal.y, portal.radius, 0, Math.PI * 2);
397
+ const gradient = ctx.createRadialGradient(
398
+ portal.x, portal.y, portal.radius * 0.3,
399
+ portal.x, portal.y, portal.radius
400
+ );
401
+ gradient.addColorStop(0, 'rgba(0, 255, 255, 0.8)');
402
+ gradient.addColorStop(1, 'rgba(0, 0, 255, 0)');
403
+ ctx.fillStyle = gradient;
404
+ ctx.fill();
405
+
406
+ // Draw event horizon
407
+ ctx.beginPath();
408
+ ctx.arc(portal.x, portal.y, portal.radius * 0.7, 0, Math.PI * 2);
409
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
410
+ ctx.fill();
411
+
412
+ // Draw spiral
413
+ for (let i = 0; i < 8; i++) {
414
+ const angle = i * (Math.PI / 4) + Date.now() / 500;
415
+ const startRadius = portal.radius * 0.7;
416
+ const endRadius = portal.radius;
417
+
418
+ ctx.beginPath();
419
+ ctx.moveTo(
420
+ portal.x + Math.cos(angle) * startRadius,
421
+ portal.y + Math.sin(angle) * startRadius
422
+ );
423
+ ctx.lineTo(
424
+ portal.x + Math.cos(angle) * endRadius,
425
+ portal.y + Math.sin(angle) * endRadius
426
+ );
427
+ ctx.strokeStyle = `rgba(0, 255, 255, ${0.5 + 0.5 * Math.sin(Date.now()/200 + i)})`;
428
+ ctx.lineWidth = 2;
429
+ ctx.stroke();
430
+ }
431
+ });
432
+
433
+ // Draw particles
434
+ particles.forEach(particle => {
435
+ ctx.fillStyle = particle.color;
436
+ ctx.beginPath();
437
+ ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
438
+ ctx.fill();
439
+ });
440
+
441
+ // Draw turtles
442
+ turtles.forEach(turtle => {
443
+ ctx.save();
444
+ ctx.translate(turtle.x + turtle.width/2, turtle.y + turtle.height/2);
445
+
446
+ // Add slight rotation based on movement direction
447
+ if (Math.abs(turtle.speedX) > 0.1) {
448
+ ctx.rotate(Math.atan2(turtle.speedY, turtle.speedX));
449
+ }
450
+
451
+ // Turtle shell
452
+ ctx.beginPath();
453
+ ctx.moveTo(-15, 0);
454
+ ctx.quadraticCurveTo(0, -25, 15, 0);
455
+ ctx.quadraticCurveTo(0, 25, -15, 0);
456
+ ctx.fillStyle = '#4CAF50';
457
+ ctx.fill();
458
+
459
+ // Turtle head
460
+ ctx.beginPath();
461
+ ctx.arc(-20, -5, 8, 0, Math.PI * 2);
462
+ ctx.fillStyle = '#4CAF50';
463
+ ctx.fill();
464
+
465
+ // Eyes
466
+ ctx.beginPath();
467
+ ctx.arc(-15, -5, 3, 0, Math.PI * 2);
468
+ ctx.fillStyle = 'black';
469
+ ctx.fill();
470
+
471
+ ctx.beginPath();
472
+ ctx.arc(-25, -5, 3, 0, Math.PI * 2);
473
+ ctx.fillStyle = 'black';
474
+ ctx.fill();
475
+
476
+ // Legs (simplified)
477
+ ctx.fillStyle = '#388E3C';
478
+ ctx.fillRect(10, -10, 5, 5);
479
+ ctx.fillRect(10, 5, 5, 5);
480
+ ctx.fillRect(-5, -15, 5, 5);
481
+ ctx.fillRect(-5, 10, 5, 5);
482
+
483
+ ctx.restore();
484
+ });
485
+
486
+ // Draw bird
487
+ ctx.save();
488
+ ctx.translate(bird.x + bird.width/2, bird.y + bird.height/2);
489
+
490
+ // Apply flip rotation if flipping
491
+ if (bird.isFlipping) {
492
+ const flipProgress = (Date.now() - lastFlipTime) / flipCooldown;
493
+ ctx.rotate(flipProgress * Math.PI * 2);
494
+ }
495
+
496
+ // Bird body
497
+ ctx.beginPath();
498
+ ctx.moveTo(-20, 0);
499
+ ctx.lineTo(10, -15);
500
+ ctx.lineTo(30, 0);
501
+ ctx.lineTo(10, 15);
502
+ ctx.closePath();
503
+ ctx.fillStyle = '#FF5722';
504
+ ctx.fill();
505
+
506
+ // Bird head
507
+ ctx.beginPath();
508
+ ctx.arc(25, 0, 10, 0, Math.PI * 2);
509
+ ctx.fillStyle = '#FF9800';
510
+ ctx.fill();
511
+
512
+ // Eye
513
+ ctx.beginPath();
514
+ ctx.arc(27, -2, 3, 0, Math.PI * 2);
515
+ ctx.fillStyle = 'white';
516
+ ctx.fill();
517
+
518
+ ctx.beginPath();
519
+ ctx.arc(27, -2, 1, 0, Math.PI * 2);
520
+ ctx.fillStyle = 'black';
521
+ ctx.fill();
522
+
523
+ // Beak
524
+ ctx.beginPath();
525
+ ctx.moveTo(35, 0);
526
+ ctx.lineTo(40, -5);
527
+ ctx.lineTo(40, 5);
528
+ ctx.closePath();
529
+ ctx.fillStyle = '#FFC107';
530
+ ctx.fill();
531
+
532
+ ctx.restore();
533
+
534
+ // Check if bird entered a portal
535
+ portals.forEach((portal, index) => {
536
+ const dx = bird.x + bird.width/2 - portal.x;
537
+ const dy = bird.y + bird.height/2 - portal.y;
538
+ const distance = Math.sqrt(dx * dx + dy * dy);
539
+
540
+ if (distance < portal.radius) {
541
+ // Travel to new universe
542
+ universe++;
543
+ universeIndicator.textContent = `Universe: ${universe}`;
544
+ backgroundHue = (backgroundHue + 60) % 360;
545
+
546
+ // Clear turtles and portals
547
+ turtles = [];
548
+ portals = [];
549
+
550
+ // Create celebration particles
551
+ createParticles(bird.x + bird.width/2, bird.y + bird.height/2, 50, 'cyan');
552
+
553
+ // Reset streak
554
+ streak = 0;
555
+ streakCounter.classList.add('hidden');
556
+ }
557
+ });
558
+ }
559
+
560
+ function drawStars() {
561
+ // Create a starfield effect
562
+ ctx.fillStyle = 'white';
563
+ for (let i = 0; i < 200; i++) {
564
+ // Use a simple hash to create consistent star positions per universe
565
+ const x = (Math.sin(i * 100 + universe * 10) * 0.5 + 0.5) * canvas.width;
566
+ const y = (Math.cos(i * 100 + universe * 10) * 0.5 + 0.5) * canvas.height;
567
+ const size = Math.random() * 1.5;
568
+
569
+ // Make some stars twinkle
570
+ const opacity = 0.5 + 0.5 * Math.sin(Date.now() / 1000 + i);
571
+
572
+ ctx.globalAlpha = opacity;
573
+ ctx.beginPath();
574
+ ctx.arc(x, y, size, 0, Math.PI * 2);
575
+ ctx.fill();
576
+ }
577
+ ctx.globalAlpha = 1;
578
+ }
579
+
580
+ function performBackflip() {
581
+ bird.isFlipping = true;
582
+ lastFlipTime = Date.now();
583
+ score += 20;
584
+
585
+ // Create flip particles
586
+ createParticles(bird.x + bird.width/2, bird.y + bird.height/2, 15, 'orange');
587
+
588
+ // End flip animation after cooldown
589
+ setTimeout(() => {
590
+ bird.isFlipping = false;
591
+
592
+ // Increase streak
593
+ streak++;
594
+ streakCounter.textContent = `Streak: ${streak}`;
595
+ streakCounter.classList.remove('hidden');
596
+
597
+ // Check for streak milestone
598
+ if (streak >= 3) {
599
+ createPortal();
600
+ streak = 0;
601
+ streakCounter.classList.add('hidden');
602
+ }
603
+ }, flipCooldown);
604
+ }
605
+
606
+ function spawnTurtle() {
607
+ if (!gameRunning) return;
608
+
609
+ const side = Math.floor(Math.random() * 4);
610
+ let x, y, speedX, speedY;
611
+
612
+ switch (side) {
613
+ case 0: // top
614
+ x = Math.random() * canvas.width;
615
+ y = -40;
616
+ speedX = (Math.random() - 0.5) * 3;
617
+ speedY = Math.random() * 2 + 1;
618
+ break;
619
+ case 1: // right
620
+ x = canvas.width + 40;
621
+ y = Math.random() * canvas.height;
622
+ speedX = -(Math.random() * 2 + 1);
623
+ speedY = (Math.random() - 0.5) * 3;
624
+ break;
625
+ case 2: // bottom
626
+ x = Math.random() * canvas.width;
627
+ y = canvas.height + 40;
628
+ speedX = (Math.random() - 0.5) * 3;
629
+ speedY = -(Math.random() * 2 + 1);
630
+ break;
631
+ case 3: // left
632
+ x = -40;
633
+ y = Math.random() * canvas.height;
634
+ speedX = Math.random() * 2 + 1;
635
+ speedY = (Math.random() - 0.5) * 3;
636
+ break;
637
+ }
638
+
639
+ turtles.push({
640
+ x,
641
+ y,
642
+ width: 40,
643
+ height: 30,
644
+ speedX,
645
+ speedY
646
+ });
647
+
648
+ // Randomly spawn between 1-3 turtles
649
+ if (Math.random() > 0.7) {
650
+ setTimeout(spawnTurtle, Math.random() * 500);
651
+ }
652
+ }
653
+
654
+ function createPortal() {
655
+ const x = Math.random() * (canvas.width - 200) + 100;
656
+ const y = Math.random() * (canvas.height - 200) + 100;
657
+
658
+ portals.push({
659
+ x,
660
+ y,
661
+ radius: 60
662
+ });
663
+
664
+ // Create portal particles
665
+ createParticles(x, y, 30, 'cyan');
666
+ }
667
+
668
+ function createParticles(x, y, count, color) {
669
+ for (let i = 0; i < count; i++) {
670
+ const angle = Math.random() * Math.PI * 2;
671
+ const speed = Math.random() * 3 + 1;
672
+
673
+ particles.push({
674
+ x,
675
+ y,
676
+ size: Math.random() * 3 + 1,
677
+ speedX: Math.cos(angle) * speed,
678
+ speedY: Math.sin(angle) * speed,
679
+ lifetime: Math.random() * 30 + 20,
680
+ color
681
+ });
682
+ }
683
+ }
684
+
685
+ function gameOver() {
686
+ gameRunning = false;
687
+ clearInterval(gameLoopInterval);
688
+ clearInterval(turtleSpawnInterval);
689
+
690
+ finalScoreDisplay.textContent = `Score: ${score}`;
691
+ universesVisitedDisplay.textContent = `Universes Visited: ${universe - 1}`;
692
+ gameOverScreen.classList.remove('hidden');
693
+ }
694
+
695
+ // Start with the start screen
696
+ startScreen.classList.remove('hidden');
697
+ </script>
698
+ </body>
699
  </html>