dlma commited on
Commit
e8198c1
·
verified ·
1 Parent(s): 936984b

make a game like pake mane - Follow Up Deployment

Browse files
Files changed (1) hide show
  1. index.html +194 -536
index.html CHANGED
@@ -3,608 +3,266 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Metro Dash - Subway Surfers Inspired Game</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
- body {
10
- margin: 0;
11
- padding: 0;
12
- overflow: hidden;
13
- touch-action: none;
14
- font-family: 'Arial', sans-serif;
15
- }
16
-
17
- #gameContainer {
18
- position: relative;
19
- width: 100vw;
20
- height: 100vh;
21
- background-color: #87CEEB;
22
- overflow: hidden;
23
- }
24
-
25
- #player {
26
- position: absolute;
27
- width: 60px;
28
- height: 100px;
29
- background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 150"><rect x="30" y="50" width="40" height="60" fill="%23FF5733"/><circle cx="50" cy="30" r="20" fill="%23FFC300"/><rect x="20" y="110" width="20" height="30" fill="%23333"/><rect x="60" y="110" width="20" height="30" fill="%23333"/></svg>');
30
- background-size: contain;
31
- z-index: 10;
32
- transition: left 0.2s ease-out;
33
- animation: bounce 0.5s infinite alternate;
34
  }
35
 
36
- .obstacle {
 
37
  position: absolute;
38
- width: 60px;
39
- height: 60px;
40
- background-color: #333;
41
- border-radius: 5px;
42
- animation: pulseObstacle 1.5s ease-in-out infinite;
43
- }
44
-
45
- .coin {
46
- position: absolute;
47
- width: 30px;
48
- height: 30px;
49
- background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="%23FFD700" stroke="%23FFA500" stroke-width="5"/></svg>');
50
- background-size: contain;
51
- z-index: 5;
52
- animation: rotateCoin 2s linear infinite;
53
- }
54
-
55
- .lane {
56
- position: absolute;
57
- width: 100%;
58
- height: 33.33%;
59
- border-top: 2px dashed white;
60
- border-bottom: 2px dashed white;
61
- }
62
-
63
- #scoreContainer {
64
- position: absolute;
65
- top: 20px;
66
- left: 20px;
67
- z-index: 100;
68
- color: white;
69
- font-size: 24px;
70
- text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
71
- }
72
-
73
- #gameOverScreen {
74
- position: absolute;
75
- top: 0;
76
- left: 0;
77
- width: 100%;
78
- height: 100%;
79
- background-color: rgba(0, 0, 0, 0.7);
80
- display: none;
81
- flex-direction: column;
82
- justify-content: center;
83
- align-items: center;
84
- z-index: 200;
85
- color: white;
86
- }
87
-
88
- #startScreen {
89
- position: absolute;
90
- top: 0;
91
- left: 0;
92
- width: 100%;
93
- height: 100%;
94
- background-color: rgba(0, 0, 0, 0.7);
95
  display: flex;
96
- flex-direction: column;
97
- justify-content: center;
98
  align-items: center;
99
- z-index: 200;
100
- color: white;
101
- }
102
-
103
- .train {
104
- position: absolute;
105
- width: 120px;
106
- height: 80px;
107
- background-color: #c00;
108
- border-radius: 10px;
109
- }
110
-
111
- @keyframes slide {
112
- from { background-position: 0 0; }
113
- to { background-position: -1000px 0; }
114
- }
115
-
116
- @keyframes bounce {
117
- 0% { transform: translateY(0); }
118
- 100% { transform: translateY(-5px); }
119
  }
120
 
121
- @keyframes rotateCoin {
122
- 0% { transform: rotate(0deg) scale(1); }
123
- 50% { transform: rotate(180deg) scale(1.1); }
124
- 100% { transform: rotate(360deg) scale(1); }
 
 
125
  }
126
 
127
- @keyframes pulseObstacle {
128
- 0% { opacity: 0.8; }
129
- 50% { opacity: 1; }
130
- 100% { opacity: 0.8; }
131
  }
132
 
133
- @keyframes fadeOut {
134
- 0% { transform: scale(1); opacity: 0.8; }
135
- 100% { transform: scale(2); opacity: 0; }
136
  }
137
 
138
- .ground {
139
- position: absolute;
140
- width: 100%;
141
- height: 33.33%;
142
- background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><rect width="50" height="100" fill="%23555"/><rect x="50" width="50" height="100" fill="%23444"/></svg>');
143
- background-size: 100px 100px;
144
- animation: slide 1s linear infinite;
145
  }
146
  </style>
147
  </head>
148
- <body class="bg-gray-900">
149
- <div id="gameContainer">
150
- <div id="scoreContainer" class="flex items-center space-x-4">
151
- <div class="flex items-center">
152
- <span>🏆</span>
153
- <span id="score">0</span>
 
 
154
  </div>
155
- <div class="flex items-center">
156
- <span>💰</span>
157
- <span id="coins">0</span>
158
  </div>
159
  </div>
160
 
161
- <div id="startScreen">
162
- <h1 class="text-5xl font-bold mb-6 text-yellow-300">METRO DASH</h1>
163
- <p class="text-xl mb-8">Swipe to change lanes and avoid obstacles!</p>
164
- <button id="startButton" class="bg-green-500 hover:bg-green-600 text-white font-bold py-3 px-8 rounded-full text-xl transition duration-300 transform hover:scale-105">
165
- START RUN
166
- </button>
167
- <div class="mt-8 flex space-x-4">
168
- <div class="text-center">
169
- <div class="w-16 h-16 mx-auto bg-gray-800 rounded-lg flex items-center justify-center mb-2">
170
- <span class="text-3xl">👆</span>
171
- </div>
172
- <p>Swipe Up</p>
173
- </div>
174
- <div class="text-center">
175
- <div class="w-16 h-16 mx-auto bg-gray-800 rounded-lg flex items-center justify-center mb-2">
176
- <span class="text-3xl">👇</span>
177
- </div>
178
- <p>Swipe Down</p>
179
- </div>
180
- <div class="text-center">
181
- <div class="w-16 h-16 mx-auto bg-gray-800 rounded-lg flex items-center justify-center mb-2">
182
- <span class="text-3xl">🔄</span>
183
- </div>
184
- <p>Jump/Roll</p>
185
- </div>
186
  </div>
187
  </div>
188
 
189
- <div id="gameOverScreen">
190
- <h1 class="text-5xl font-bold mb-4 text-red-500">GAME OVER</h1>
191
- <div class="bg-gray-800 p-6 rounded-lg shadow-lg mb-6 text-center">
192
- <p class="text-2xl mb-2">Score: <span id="finalScore">0</span></p>
193
- <p class="text-2xl">Coins: <span id="finalCoins">0</span></p>
194
- </div>
195
- <button id="restartButton" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-3 px-8 rounded-full text-xl transition duration-300 transform hover:scale-105">
196
- PLAY AGAIN
197
  </button>
198
  </div>
199
 
200
- <div class="ground" style="top: 0%;"></div>
201
- <div class="ground" style="top: 33.33%;"></div>
202
- <div class="ground" style="top: 66.66%;"></div>
203
-
204
- <div id="player"></div>
 
 
 
 
205
  </div>
206
-
207
  <script>
208
- // Game variables
209
- let score = 0;
210
- let coins = 0;
211
- let gameSpeed = 5;
212
- let gameRunning = false;
213
- let playerLane = 1; // 0: top, 1: middle, 2: bottom
214
- let obstacles = [];
215
- let coinsArray = [];
216
- let trains = [];
217
- let animationId;
218
- let obstacleSpawnRate = 100; // frames
219
- let coinSpawnRate = 50; // frames
220
- let trainSpawnRate = 200; // frames
221
- let frameCount = 0;
222
- let isJumping = false;
223
- let isRolling = false;
224
-
225
- // DOM elements
226
- const gameContainer = document.getElementById('gameContainer');
227
- const player = document.getElementById('player');
228
- const scoreElement = document.getElementById('score');
229
- const coinsElement = document.getElementById('coins');
230
- const gameOverScreen = document.getElementById('gameOverScreen');
231
- const startScreen = document.getElementById('startScreen');
232
- const startButton = document.getElementById('startButton');
233
- const restartButton = document.getElementById('restartButton');
234
- const finalScoreElement = document.getElementById('finalScore');
235
- const finalCoinsElement = document.getElementById('finalCoins');
236
 
237
- // Game dimensions
238
- const gameWidth = gameContainer.offsetWidth;
239
- const gameHeight = gameContainer.offsetHeight;
240
- const laneHeight = gameHeight / 3;
241
-
242
- // Initialize player position
243
- function initPlayer() {
244
- player.style.width = '60px';
245
- player.style.height = '100px';
246
- player.style.left = '100px';
247
- moveToLane(playerLane);
248
- isJumping = false;
249
- isRolling = false;
250
- player.style.transform = 'none';
251
- }
252
-
253
- // Move player to specified lane (0, 1, or 2)
254
- function moveToLane(lane) {
255
- playerLane = lane;
256
- player.style.top = `${lane * laneHeight + (laneHeight - 100) / 2}px`;
257
- }
258
-
259
- // Create a new obstacle
260
- function createObstacle() {
261
- const obstacle = document.createElement('div');
262
- obstacle.className = 'obstacle';
263
-
264
- // Random lane (0, 1, or 2)
265
- const lane = Math.floor(Math.random() * 3);
266
 
267
- // Position obstacle at the right edge of the screen
268
- obstacle.style.left = `${gameWidth}px`;
269
- obstacle.style.top = `${lane * laneHeight + (laneHeight - 60) / 2}px`;
270
 
271
- // Random obstacle type (30% chance of being a train)
272
- if (Math.random() < 0.3) {
273
- obstacle.classList.add('train');
274
- obstacle.style.width = '120px';
275
- obstacle.style.height = '80px';
276
- obstacle.style.top = `${lane * laneHeight + (laneHeight - 80) / 2}px`;
277
- } else {
278
- // Random color for regular obstacles
279
- const colors = ['#333', '#555', '#777', '#8B4513', '#A0522D'];
280
- obstacle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
281
- }
282
 
283
- gameContainer.appendChild(obstacle);
284
- obstacles.push({
285
- element: obstacle,
286
- lane: lane,
287
- isTrain: obstacle.classList.contains('train')
288
- });
289
  }
290
 
291
- // Create a new coin
292
- function createCoin() {
293
- const coin = document.createElement('div');
294
- coin.className = 'coin';
295
 
296
- // Random lane (0, 1, or 2)
297
- const lane = Math.floor(Math.random() * 3);
 
 
298
 
299
- // Position coin at the right edge of the screen
300
- coin.style.left = `${gameWidth}px`;
301
- coin.style.top = `${lane * laneHeight + (laneHeight - 30) / 2}px`;
302
 
303
- gameContainer.appendChild(coin);
304
- coinsArray.push({
305
- element: coin,
306
- lane: lane
307
- });
308
- }
309
-
310
- // Update obstacle positions
311
- function updateObstacles() {
312
- for (let i = obstacles.length - 1; i >= 0; i--) {
313
- const obstacle = obstacles[i];
314
- const currentLeft = parseInt(obstacle.element.style.left);
315
- const newLeft = currentLeft - gameSpeed;
316
-
317
- obstacle.element.style.left = `${newLeft}px`;
318
-
319
- // Remove obstacle if it's off screen
320
- if (newLeft < -100) {
321
- gameContainer.removeChild(obstacle.element);
322
- obstacles.splice(i, 1);
323
- }
324
-
325
- // Check for collision
326
- if (checkCollision(player, obstacle.element) && obstacle.lane === playerLane && !isJumping && !isRolling) {
327
- gameOver();
328
- return;
329
- }
330
- }
331
- }
332
-
333
- // Update coin positions
334
- function updateCoins() {
335
- for (let i = coinsArray.length - 1; i >= 0; i--) {
336
- const coin = coinsArray[i];
337
- const currentLeft = parseInt(coin.element.style.left);
338
- const newLeft = currentLeft - gameSpeed;
339
-
340
- coin.element.style.left = `${newLeft}px`;
341
-
342
- // Remove coin if it's off screen
343
- if (newLeft < -50) {
344
- gameContainer.removeChild(coin.element);
345
- coinsArray.splice(i, 1);
346
- }
347
 
348
- // Check for collection
349
- if (checkCollision(player, coin.element) && coin.lane === playerLane) {
350
- coins++;
351
- coinsElement.textContent = coins;
 
 
 
 
 
352
 
353
- // Create sparkle effect
354
- const sparkle = document.createElement('div');
355
- sparkle.style.position = 'absolute';
356
- sparkle.style.left = coin.element.style.left;
357
- sparkle.style.top = coin.element.style.top;
358
- sparkle.style.width = '40px';
359
- sparkle.style.height = '40px';
360
- sparkle.style.backgroundImage = 'radial-gradient(circle, yellow, transparent)';
361
- sparkle.style.zIndex = '15';
362
- sparkle.style.pointerEvents = 'none';
363
- sparkle.style.opacity = '0.8';
364
- sparkle.style.animation = 'fadeOut 0.5s forwards';
365
 
366
- gameContainer.appendChild(sparkle);
367
  setTimeout(() => {
368
- gameContainer.removeChild(sparkle);
369
- }, 500);
370
-
371
- gameContainer.removeChild(coin.element);
372
- coinsArray.splice(i, 1);
373
-
374
- // Play coin sound
375
- playSound('coin');
376
  }
377
- }
 
 
 
 
 
 
378
  }
379
 
380
- // Check collision between two elements
381
- function checkCollision(element1, element2) {
382
- const rect1 = element1.getBoundingClientRect();
383
- const rect2 = element2.getBoundingClientRect();
384
-
385
- return !(
386
- rect1.right < rect2.left ||
387
- rect1.left > rect2.right ||
388
- rect1.bottom < rect2.top ||
389
- rect1.top > rect2.bottom
390
- );
391
  }
392
 
393
- // Game over function
394
- function gameOver() {
395
- gameRunning = false;
396
- cancelAnimationFrame(animationId);
397
 
398
- // Show game over screen
399
- finalScoreElement.textContent = score;
400
- finalCoinsElement.textContent = coins;
401
- gameOverScreen.style.display = 'flex';
402
 
403
- // Play crash sound
404
- playSound('crash');
 
405
  }
406
 
407
- // Reset game state
408
- function resetGame() {
409
- // Clear all obstacles and coins
410
- obstacles.forEach(obstacle => {
411
- if (obstacle.element.parentNode) {
412
- gameContainer.removeChild(obstacle.element);
413
- }
414
- });
415
-
416
- coinsArray.forEach(coin => {
417
- if (coin.element.parentNode) {
418
- gameContainer.removeChild(coin.element);
419
- }
420
- });
421
-
422
- obstacles = [];
423
- coinsArray = [];
424
-
425
- // Reset player
426
- initPlayer();
427
 
428
- // Reset score and speed
429
  score = 0;
430
- coins = 0;
431
- gameSpeed = 5;
432
- frameCount = 0;
 
433
 
434
- // Update UI
435
- scoreElement.textContent = score;
436
- coinsElement.textContent = coins;
437
- }
438
-
439
- // Main game loop
440
- function gameLoop() {
441
- if (!gameRunning) return;
442
 
443
- frameCount++;
 
 
444
 
445
- // Spawn new obstacles and coins
446
- if (frameCount % obstacleSpawnRate === 0) {
447
- createObstacle();
448
-
449
- // Increase difficulty over time
450
- if (obstacleSpawnRate > 40) {
451
- obstacleSpawnRate -= 1;
452
- }
453
- }
454
-
455
- if (frameCount % coinSpawnRate === 0) {
456
- createCoin();
457
- }
458
-
459
- // Update game elements
460
- updateObstacles();
461
- updateCoins();
462
-
463
- // Increase score
464
- score++;
465
- scoreElement.textContent = Math.floor(score / 10);
466
-
467
- // Gradually increase game speed
468
- if (frameCount % 500 === 0) {
469
- gameSpeed += 0.5;
470
- }
471
-
472
- // End jump/roll animation after short time
473
- if (isJumping && frameCount % 30 === 0) {
474
- isJumping = false;
475
- player.style.transform = 'none';
476
- }
477
-
478
- if (isRolling && frameCount % 40 === 0) {
479
- isRolling = false;
480
- player.style.transform = 'none';
481
- player.style.height = '100px';
482
- }
483
-
484
- animationId = requestAnimationFrame(gameLoop);
485
- }
486
-
487
- // Start the game
488
- function startGame() {
489
- resetGame();
490
- gameRunning = true;
491
- startScreen.style.display = 'none';
492
- gameOverScreen.style.display = 'none';
493
- gameLoop();
494
  }
495
 
496
- // Play sound effects
497
- function playSound(type) {
498
- // In a real game, you would play actual sound files here
499
- console.log(`Playing ${type} sound`);
500
- }
501
-
502
- // Handle swipe gestures
503
- let touchStartY = 0;
504
- let touchEndY = 0;
505
-
506
- function handleTouchStart(e) {
507
- touchStartY = e.changedTouches[0].screenY;
508
- }
509
-
510
- function handleTouchEnd(e) {
511
- if (!gameRunning) return;
512
 
513
- touchEndY = e.changedTouches[0].screenY;
514
- const diffY = touchStartY - touchEndY;
515
 
516
- // Swipe up
517
- if (diffY > 50) {
518
- if (playerLane > 0) {
519
- moveToLane(playerLane - 1);
520
- playSound('swipe');
521
- } else {
522
- // Jump if already in top lane
523
- if (!isJumping && !isRolling) {
524
- isJumping = true;
525
- player.style.transform = 'translateY(-30px)';
526
- playSound('jump');
527
- }
528
- }
529
- }
530
- // Swipe down
531
- else if (diffY < -50) {
532
- if (playerLane < 2) {
533
- moveToLane(playerLane + 1);
534
- playSound('swipe');
535
- } else {
536
- // Roll if already in bottom lane
537
- if (!isJumping && !isRolling) {
538
- isRolling = true;
539
- player.style.height = '50px';
540
- player.style.transform = 'rotate(360deg)';
541
- playSound('roll');
542
- }
543
- }
544
- }
545
- }
546
-
547
- // Keyboard controls
548
- function handleKeyDown(e) {
549
- if (!gameRunning) return;
550
 
551
- switch(e.key) {
552
- case 'ArrowUp':
553
- if (playerLane > 0) {
554
- moveToLane(playerLane - 1);
555
- playSound('swipe');
556
- } else {
557
- // Jump if already in top lane
558
- if (!isJumping && !isRolling) {
559
- isJumping = true;
560
- player.style.transform = 'translateY(-30px)';
561
- playSound('jump');
562
- }
563
- }
564
- break;
565
- case 'ArrowDown':
566
- if (playerLane < 2) {
567
- moveToLane(playerLane + 1);
568
- playSound('swipe');
569
- } else {
570
- // Roll if already in bottom lane
571
- if (!isJumping && !isRolling) {
572
- isRolling = true;
573
- player.style.height = '50px';
574
- player.style.transform = 'rotate(360deg)';
575
- playSound('roll');
576
- }
577
- }
578
- break;
579
- case ' ':
580
- // Jump or roll based on current lane
581
- if (playerLane === 0 && !isJumping && !isRolling) {
582
- isJumping = true;
583
- player.style.transform = 'translateY(-30px)';
584
- playSound('jump');
585
- } else if (playerLane === 2 && !isJumping && !isRolling) {
586
- isRolling = true;
587
- player.style.height = '50px';
588
- player.style.transform = 'rotate(360deg)';
589
- playSound('roll');
590
- }
591
- break;
592
- }
593
  }
594
 
595
- // Event listeners
596
- startButton.addEventListener('click', startGame);
597
- restartButton.addEventListener('click', startGame);
598
-
599
- // Touch controls for mobile
600
- gameContainer.addEventListener('touchstart', handleTouchStart, false);
601
- gameContainer.addEventListener('touchend', handleTouchEnd, false);
 
 
602
 
603
- // Keyboard controls for desktop
604
- document.addEventListener('keydown', handleKeyDown);
605
 
606
- // Initialize player position
607
- initPlayer();
 
 
608
  </script>
609
  <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=dlma/subway" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
610
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Pake Mane Game</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <style>
9
+ @keyframes fall {
10
+ from { transform: translateY(-100px); }
11
+ to { transform: translateY(calc(100vh - 100px)); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
13
 
14
+ .falling-item {
15
+ animation: fall linear forwards;
16
  position: absolute;
17
+ width: 50px;
18
+ height: 50px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  display: flex;
 
 
20
  align-items: center;
21
+ justify-content: center;
22
+ font-size: 24px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
+ #gameArea {
26
+ position: relative;
27
+ width: 100%;
28
+ height: calc(100vh - 100px);
29
+ overflow: hidden;
30
+ background-color: #f0f9ff;
31
  }
32
 
33
+ #basket {
34
+ transition: left 0.1s ease-out;
 
 
35
  }
36
 
37
+ .score-bounce {
38
+ animation: scoreBounce 0.5s;
 
39
  }
40
 
41
+ @keyframes scoreBounce {
42
+ 0%, 100% { transform: scale(1); }
43
+ 50% { transform: scale(1.5); }
 
 
 
 
44
  }
45
  </style>
46
  </head>
47
+ <body class="bg-blue-50 min-h-screen flex flex-col items-center">
48
+ <div class="container mx-auto px-4 py-8">
49
+ <h1 class="text-4xl font-bold text-center text-blue-600 mb-2">Pake Mane</h1>
50
+ <p class="text-center text-blue-500 mb-6">Catch the falling items with your basket!</p>
51
+
52
+ <div class="flex justify-between items-center mb-4">
53
+ <div class="text-xl font-semibold">
54
+ Score: <span id="score" class="text-blue-600">0</span>
55
  </div>
56
+ <div class="text-xl font-semibold">
57
+ Time: <span id="time" class="text-blue-600">60</span>s
 
58
  </div>
59
  </div>
60
 
61
+ <div id="gameArea" class="border-2 border-blue-300 rounded-lg bg-gradient-to-b from-blue-100 to-blue-200">
62
+ <div id="basket" class="absolute bottom-0 w-24 h-16 bg-orange-500 rounded-t-lg flex items-center justify-center">
63
+ <div class="w-full h-2 bg-orange-700 rounded-full"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  </div>
65
  </div>
66
 
67
+ <div class="mt-6 flex justify-center space-x-4">
68
+ <button id="startBtn" class="px-6 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition">
69
+ Start Game
70
+ </button>
71
+ <button id="resetBtn" class="px-6 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition">
72
+ Reset
 
 
73
  </button>
74
  </div>
75
 
76
+ <div class="mt-8 bg-white p-4 rounded-lg shadow-md">
77
+ <h2 class="text-xl font-semibold text-blue-600 mb-2">How to Play</h2>
78
+ <ul class="list-disc pl-5 space-y-1">
79
+ <li>Use mouse or touch to move the basket left and right</li>
80
+ <li>Catch as many items as you can in 60 seconds</li>
81
+ <li>Different items give different points</li>
82
+ <li>Avoid the bombs that deduct points!</li>
83
+ </ul>
84
+ </div>
85
  </div>
86
+
87
  <script>
88
+ const gameArea = document.getElementById('gameArea');
89
+ const basket = document.getElementById('basket');
90
+ const scoreDisplay = document.getElementById('score');
91
+ const timeDisplay = document.getElementById('time');
92
+ const startBtn = document.getElementById('startBtn');
93
+ const resetBtn = document.getElementById('resetBtn');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
+ let score = 0;
96
+ let timeLeft = 60;
97
+ let gameInterval;
98
+ let timeInterval;
99
+ let isGameRunning = false;
100
+ let gameWidth = gameArea.offsetWidth;
101
+ let basketWidth = basket.offsetWidth;
102
+
103
+ // Items with their points and emojis
104
+ const items = [
105
+ { emoji: '🍎', points: 1, color: 'bg-red-400' },
106
+ { emoji: '🍌', points: 2, color: 'bg-yellow-300' },
107
+ { emoji: '🍇', points: 3, color: 'bg-purple-400' },
108
+ { emoji: '🍒', points: 2, color: 'bg-red-500' },
109
+ { emoji: '💣', points: -5, color: 'bg-gray-700' }
110
+ ];
111
+
112
+ // Update basket position on mouse/touch move
113
+ gameArea.addEventListener('mousemove', moveBasket);
114
+ gameArea.addEventListener('touchmove', (e) => {
115
+ e.preventDefault();
116
+ const touch = e.touches[0];
117
+ moveBasket({ clientX: touch.clientX });
118
+ });
119
+
120
+ function moveBasket(e) {
121
+ if (!isGameRunning) return;
 
 
122
 
123
+ const gameRect = gameArea.getBoundingClientRect();
124
+ let newPosition = e.clientX - gameRect.left - basketWidth / 2;
 
125
 
126
+ // Keep basket within game area
127
+ newPosition = Math.max(0, Math.min(newPosition, gameWidth - basketWidth));
 
 
 
 
 
 
 
 
 
128
 
129
+ basket.style.left = `${newPosition}px`;
 
 
 
 
 
130
  }
131
 
132
+ function createFallingItem() {
133
+ if (!isGameRunning) return;
 
 
134
 
135
+ const item = items[Math.floor(Math.random() * items.length)];
136
+ const itemElement = document.createElement('div');
137
+ itemElement.className = `falling-item ${item.color} rounded-full shadow-md`;
138
+ itemElement.textContent = item.emoji;
139
 
140
+ const startPosition = Math.random() * (gameWidth - 50);
141
+ itemElement.style.left = `${startPosition}px`;
 
142
 
143
+ // Randomize falling speed
144
+ const duration = 3 + Math.random() * 4;
145
+ itemElement.style.animationDuration = `${duration}s`;
146
+
147
+ gameArea.appendChild(itemElement);
148
+
149
+ // Check for collision
150
+ const checkCollision = setInterval(() => {
151
+ const itemRect = itemElement.getBoundingClientRect();
152
+ const basketRect = basket.getBoundingClientRect();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
+ if (
155
+ itemRect.bottom >= basketRect.top &&
156
+ itemRect.right >= basketRect.left &&
157
+ itemRect.left <= basketRect.right
158
+ ) {
159
+ // Collision detected
160
+ clearInterval(checkCollision);
161
+ updateScore(item.points);
162
+ itemElement.remove();
163
 
164
+ // Show feedback
165
+ const feedback = document.createElement('div');
166
+ feedback.className = 'absolute text-xl font-bold';
167
+ feedback.textContent = item.points > 0 ? `+${item.points}` : `${item.points}`;
168
+ feedback.style.color = item.points > 0 ? 'green' : 'red';
169
+ feedback.style.left = `${itemRect.left}px`;
170
+ feedback.style.top = `${itemRect.top}px`;
171
+ gameArea.appendChild(feedback);
 
 
 
 
172
 
173
+ // Animate feedback
174
  setTimeout(() => {
175
+ feedback.style.transition = 'all 0.5s';
176
+ feedback.style.opacity = '0';
177
+ feedback.style.transform = 'translateY(-20px)';
178
+ setTimeout(() => feedback.remove(), 500);
179
+ }, 100);
 
 
 
180
  }
181
+
182
+ // Remove if out of bounds
183
+ if (itemRect.top >= gameArea.offsetHeight) {
184
+ clearInterval(checkCollision);
185
+ itemElement.remove();
186
+ }
187
+ }, 16);
188
  }
189
 
190
+ function updateScore(points) {
191
+ score += points;
192
+ score = Math.max(0, score); // Prevent negative score
193
+ scoreDisplay.textContent = score;
194
+ scoreDisplay.classList.add('score-bounce');
195
+ setTimeout(() => scoreDisplay.classList.remove('score-bounce'), 500);
 
 
 
 
 
196
  }
197
 
198
+ function updateTimer() {
199
+ timeLeft--;
200
+ timeDisplay.textContent = timeLeft;
 
201
 
202
+ if (timeLeft <= 10) {
203
+ timeDisplay.classList.add('text-red-500');
204
+ }
 
205
 
206
+ if (timeLeft <= 0) {
207
+ endGame();
208
+ }
209
  }
210
 
211
+ function startGame() {
212
+ if (isGameRunning) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
+ isGameRunning = true;
215
  score = 0;
216
+ timeLeft = 60;
217
+ scoreDisplay.textContent = score;
218
+ timeDisplay.textContent = timeLeft;
219
+ timeDisplay.classList.remove('text-red-500');
220
 
221
+ // Clear any existing items
222
+ document.querySelectorAll('.falling-item').forEach(item => item.remove());
 
 
 
 
 
 
223
 
224
+ // Start game loops
225
+ gameInterval = setInterval(createFallingItem, 800);
226
+ timeInterval = setInterval(updateTimer, 1000);
227
 
228
+ startBtn.disabled = true;
229
+ startBtn.classList.add('opacity-50');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  }
231
 
232
+ function endGame() {
233
+ isGameRunning = false;
234
+ clearInterval(gameInterval);
235
+ clearInterval(timeInterval);
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ startBtn.disabled = false;
238
+ startBtn.classList.remove('opacity-50');
239
 
240
+ // Show game over message
241
+ const gameOver = document.createElement('div');
242
+ gameOver.className = 'absolute inset-0 flex items-center justify-center bg-black bg-opacity-70 text-white text-3xl font-bold';
243
+ gameOver.textContent = `Game Over! Score: ${score}`;
244
+ gameArea.appendChild(gameOver);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
+ setTimeout(() => gameOver.remove(), 3000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
248
 
249
+ function resetGame() {
250
+ endGame();
251
+ score = 0;
252
+ timeLeft = 60;
253
+ scoreDisplay.textContent = score;
254
+ timeDisplay.textContent = timeLeft;
255
+ timeDisplay.classList.remove('text-red-500');
256
+ document.querySelectorAll('.falling-item').forEach(item => item.remove());
257
+ }
258
 
259
+ startBtn.addEventListener('click', startGame);
260
+ resetBtn.addEventListener('click', resetGame);
261
 
262
+ // Handle window resize
263
+ window.addEventListener('resize', () => {
264
+ gameWidth = gameArea.offsetWidth;
265
+ });
266
  </script>
267
  <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=dlma/subway" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
268
  </html>