sreeramajay commited on
Commit
1e9b46f
·
verified ·
1 Parent(s): 46238a5

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +842 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Pixel Rush
3
- emoji: 📈
4
- colorFrom: pink
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: pixel-rush
3
+ emoji: 🐳
4
+ colorFrom: green
5
+ colorTo: green
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,842 @@
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>Pixel Rush | Light Trail Platformer</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
+ :root {
13
+ --neon-blue: #00f7ff;
14
+ --neon-pink: #ff00f7;
15
+ --neon-purple: #9d00ff;
16
+ --dark-bg: #0f0a1a;
17
+ }
18
+
19
+ body {
20
+ font-family: 'Press Start 2P', cursive;
21
+ background-color: var(--dark-bg);
22
+ overflow: hidden;
23
+ touch-action: none;
24
+ user-select: none;
25
+ }
26
+
27
+ .game-container {
28
+ position: relative;
29
+ width: 100vw;
30
+ height: 100vh;
31
+ overflow: hidden;
32
+ }
33
+
34
+ #gameCanvas {
35
+ background-color: #000;
36
+ display: block;
37
+ image-rendering: pixelated;
38
+ }
39
+
40
+ .neon-text {
41
+ text-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-pink);
42
+ color: white;
43
+ }
44
+
45
+ .neon-border {
46
+ box-shadow: 0 0 10px var(--neon-blue), 0 0 20px var(--neon-pink), inset 0 0 10px var(--neon-blue);
47
+ border: 2px solid var(--neon-blue);
48
+ }
49
+
50
+ .pixel-button {
51
+ transition: all 0.2s;
52
+ position: relative;
53
+ overflow: hidden;
54
+ }
55
+
56
+ .pixel-button:hover {
57
+ transform: translateY(-2px);
58
+ box-shadow: 0 0 15px var(--neon-blue), 0 0 30px var(--neon-pink);
59
+ }
60
+
61
+ .pixel-button:active {
62
+ transform: translateY(1px);
63
+ }
64
+
65
+ .pixel-button::before {
66
+ content: '';
67
+ position: absolute;
68
+ top: -10px;
69
+ left: -10px;
70
+ right: -10px;
71
+ bottom: -10px;
72
+ background: linear-gradient(45deg, var(--neon-blue), var(--neon-pink), var(--neon-purple));
73
+ z-index: -1;
74
+ filter: blur(20px);
75
+ opacity: 0;
76
+ transition: opacity 0.3s;
77
+ }
78
+
79
+ .pixel-button:hover::before {
80
+ opacity: 0.7;
81
+ }
82
+
83
+ .glow {
84
+ animation: pulse 2s infinite alternate;
85
+ }
86
+
87
+ @keyframes pulse {
88
+ 0% { opacity: 0.7; }
89
+ 100% { opacity: 1; }
90
+ }
91
+
92
+ .menu-screen {
93
+ background: rgba(15, 10, 26, 0.9);
94
+ backdrop-filter: blur(5px);
95
+ }
96
+
97
+ .score-display {
98
+ background: rgba(0, 0, 0, 0.7);
99
+ border: 2px solid var(--neon-blue);
100
+ }
101
+
102
+ .mobile-controls {
103
+ touch-action: none;
104
+ }
105
+
106
+ .mobile-btn {
107
+ touch-action: none;
108
+ background: rgba(0, 0, 0, 0.5);
109
+ border: 2px solid var(--neon-blue);
110
+ }
111
+
112
+ .mobile-btn:active {
113
+ background: var(--neon-blue);
114
+ }
115
+ </style>
116
+ </head>
117
+ <body>
118
+ <div class="game-container flex items-center justify-center">
119
+ <canvas id="gameCanvas"></canvas>
120
+
121
+ <!-- Main Menu -->
122
+ <div id="mainMenu" class="menu-screen absolute inset-0 flex flex-col items-center justify-center gap-8 neon-text">
123
+ <h1 class="text-5xl md:text-7xl mb-4 glow">PIXEL RUSH</h1>
124
+
125
+ <div class="flex flex-col gap-4 w-full max-w-md px-4">
126
+ <button id="startBtn" class="pixel-button neon-border bg-black py-4 px-8 text-xl neon-text">
127
+ START GAME
128
+ </button>
129
+ <button id="howToBtn" class="pixel-button neon-border bg-black py-4 px-8 text-xl neon-text">
130
+ HOW TO PLAY
131
+ </button>
132
+ <button id="settingsBtn" class="pixel-button neon-border bg-black py-4 px-8 text-xl neon-text">
133
+ SETTINGS
134
+ </button>
135
+ </div>
136
+
137
+ <div class="absolute bottom-4 text-sm opacity-70">
138
+ Use arrow keys or touch controls
139
+ </div>
140
+ </div>
141
+
142
+ <!-- How To Play -->
143
+ <div id="howToMenu" class="menu-screen absolute inset-0 hidden flex-col items-center justify-center gap-6 neon-text p-4">
144
+ <h2 class="text-3xl mb-6">HOW TO PLAY</h2>
145
+
146
+ <div class="max-w-md bg-black bg-opacity-70 neon-border p-6 text-left text-sm leading-relaxed">
147
+ <div class="mb-4 flex items-start gap-3">
148
+ <i class="fas fa-arrow-up mt-1 text-purple-300"></i>
149
+ <p>Press UP to jump over obstacles and gaps</p>
150
+ </div>
151
+ <div class="mb-4 flex items-start gap-3">
152
+ <i class="fas fa-arrow-left mt-1 text-blue-300"></i>
153
+ <i class="fas fa-arrow-right mt-1 text-blue-300"></i>
154
+ <p>Move LEFT/RIGHT to navigate platforms</p>
155
+ </div>
156
+ <div class="mb-4 flex items-start gap-3">
157
+ <i class="fas fa-bolt mt-1 text-yellow-300"></i>
158
+ <p>Collect energy orbs to grow your trail</p>
159
+ </div>
160
+ <div class="mb-4 flex items-start gap-3">
161
+ <i class="fas fa-skull mt-1 text-red-300"></i>
162
+ <p>Avoid touching your trail or falling off</p>
163
+ </div>
164
+ <div class="mt-6 text-center">
165
+ <p class="text-purple-300">The longer your trail, the higher your score!</p>
166
+ </div>
167
+ </div>
168
+
169
+ <button id="backFromHowToBtn" class="pixel-button neon-border bg-black py-3 px-6 mt-6 neon-text">
170
+ BACK
171
+ </button>
172
+ </div>
173
+
174
+ <!-- Settings -->
175
+ <div id="settingsMenu" class="menu-screen absolute inset-0 hidden flex-col items-center justify-center gap-6 neon-text p-4">
176
+ <h2 class="text-3xl mb-6">SETTINGS</h2>
177
+
178
+ <div class="max-w-md bg-black bg-opacity-70 neon-border p-6 w-full">
179
+ <div class="mb-6">
180
+ <label class="block mb-2">Game Speed</label>
181
+ <div class="flex gap-2">
182
+ <button data-speed="0.8" class="speed-btn pixel-button neon-border bg-black py-2 px-4 text-sm active">Slow</button>
183
+ <button data-speed="1.2" class="speed-btn pixel-button neon-border bg-black py-2 px-4 text-sm">Normal</button>
184
+ <button data-speed="1.6" class="speed-btn pixel-button neon-border bg-black py-2 px-4 text-sm">Fast</button>
185
+ </div>
186
+ </div>
187
+
188
+ <div class="mb-6">
189
+ <label class="block mb-2">Trail Style</label>
190
+ <div class="flex gap-2 flex-wrap">
191
+ <button data-trail="solid" class="trail-btn pixel-button neon-border bg-black py-2 px-4 text-sm active">Solid</button>
192
+ <button data-trail="glow" class="trail-btn pixel-button neon-border bg-black py-2 px-4 text-sm">Glow</button>
193
+ <button data-trail="pulse" class="trail-btn pixel-button neon-border bg-black py-2 px-4 text-sm">Pulse</button>
194
+ <button data-trail="rainbow" class="trail-btn pixel-button neon-border bg-black py-2 px-4 text-sm">Rainbow</button>
195
+ </div>
196
+ </div>
197
+
198
+ <div class="flex items-center justify-between">
199
+ <label for="soundToggle" class="cursor-pointer">Sound Effects</label>
200
+ <div class="relative">
201
+ <input type="checkbox" id="soundToggle" class="hidden" checked>
202
+ <div class="toggle-bg bg-gray-700 w-12 h-6 rounded-full">
203
+ <div class="toggle-circle absolute left-0 top-0 bg-blue-400 w-6 h-6 rounded-full transition-transform"></div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+
209
+ <button id="backFromSettingsBtn" class="pixel-button neon-border bg-black py-3 px-6 mt-6 neon-text">
210
+ BACK
211
+ </button>
212
+ </div>
213
+
214
+ <!-- Game Over -->
215
+ <div id="gameOverMenu" class="menu-screen absolute inset-0 hidden flex-col items-center justify-center gap-6 neon-text">
216
+ <h2 class="text-4xl text-red-400 mb-2">GAME OVER</h2>
217
+ <div class="text-xl mb-2">Your Score:</div>
218
+ <div id="finalScore" class="text-5xl text-yellow-300 mb-8">0</div>
219
+
220
+ <div class="flex flex-col gap-4 w-full max-w-md px-4">
221
+ <button id="restartBtn" class="pixel-button neon-border bg-black py-4 px-8 text-xl neon-text">
222
+ PLAY AGAIN
223
+ </button>
224
+ <button id="menuBtn" class="pixel-button neon-border bg-black py-4 px-8 text-xl neon-text">
225
+ MAIN MENU
226
+ </button>
227
+ </div>
228
+ </div>
229
+
230
+ <!-- In-Game UI -->
231
+ <div id="gameUI" class="absolute top-0 left-0 right-0 p-4 hidden">
232
+ <div class="flex justify-between items-center">
233
+ <div class="score-display py-2 px-4 rounded">
234
+ <span class="text-yellow-300">SCORE: </span>
235
+ <span id="scoreValue" class="text-white">0</span>
236
+ </div>
237
+ <div class="score-display py-2 px-4 rounded">
238
+ <span class="text-blue-300">LENGTH: </span>
239
+ <span id="lengthValue" class="text-white">1</span>
240
+ </div>
241
+ </div>
242
+ </div>
243
+
244
+ <!-- Mobile Controls (hidden by default) -->
245
+ <div id="mobileControls" class="absolute bottom-0 left-0 right-0 p-4 hidden mobile-controls">
246
+ <div class="flex justify-between">
247
+ <div class="flex gap-4">
248
+ <button id="mobileLeft" class="mobile-btn w-16 h-16 rounded-full flex items-center justify-center">
249
+ <i class="fas fa-arrow-left text-2xl"></i>
250
+ </button>
251
+ <button id="mobileRight" class="mobile-btn w-16 h-16 rounded-full flex items-center justify-center">
252
+ <i class="fas fa-arrow-right text-2xl"></i>
253
+ </button>
254
+ </div>
255
+ <button id="mobileUp" class="mobile-btn w-16 h-16 rounded-full flex items-center justify-center">
256
+ <i class="fas fa-arrow-up text-2xl"></i>
257
+ </button>
258
+ </div>
259
+ </div>
260
+ </div>
261
+
262
+ <script>
263
+ // Game variables
264
+ let canvas, ctx;
265
+ let gameWidth, gameHeight;
266
+ let gameActive = false;
267
+ let score = 0;
268
+ let trailLength = 1;
269
+ let gameSpeed = 0.8; // Default to slow speed
270
+ let trailStyle = 'solid';
271
+ let soundEnabled = true;
272
+ let isMobile = false;
273
+
274
+ // Player variables
275
+ let player = {
276
+ x: 100,
277
+ y: 300,
278
+ width: 20,
279
+ height: 20,
280
+ velocityY: 0,
281
+ gravity: 0.3, // Reduced gravity for slower fall
282
+ jumpForce: -9, // Reduced jump force for lower jumps
283
+ isJumping: false,
284
+ speed: 0
285
+ };
286
+
287
+ // Trail segments
288
+ let trail = [];
289
+ const maxTrailLength = 100;
290
+
291
+ // Platforms
292
+ let platforms = [];
293
+ const platformHeight = 20;
294
+
295
+ // Collectibles
296
+ let collectibles = [];
297
+
298
+ // Obstacles
299
+ let obstacles = [];
300
+
301
+ // Initialize game
302
+ function init() {
303
+ canvas = document.getElementById('gameCanvas');
304
+ ctx = canvas.getContext('2d');
305
+
306
+ // Check if mobile
307
+ isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
308
+ if (isMobile) {
309
+ document.getElementById('mobileControls').classList.remove('hidden');
310
+ }
311
+
312
+ resizeCanvas();
313
+ setupEventListeners();
314
+ generateInitialPlatforms();
315
+ }
316
+
317
+ // Resize canvas to window
318
+ function resizeCanvas() {
319
+ gameWidth = window.innerWidth;
320
+ gameHeight = window.innerHeight;
321
+
322
+ canvas.width = gameWidth;
323
+ canvas.height = gameHeight;
324
+
325
+ // Adjust player position if game is active
326
+ if (gameActive) {
327
+ player.y = Math.min(player.y, gameHeight - player.height - platformHeight);
328
+ }
329
+ }
330
+
331
+ // Set up event listeners
332
+ function setupEventListeners() {
333
+ // Window resize
334
+ window.addEventListener('resize', resizeCanvas);
335
+
336
+ // Keyboard controls
337
+ window.addEventListener('keydown', handleKeyDown);
338
+ window.addEventListener('keyup', handleKeyUp);
339
+
340
+ // Mobile controls
341
+ document.getElementById('mobileLeft').addEventListener('touchstart', () => movePlayer('left'));
342
+ document.getElementById('mobileLeft').addEventListener('touchend', () => stopPlayer());
343
+ document.getElementById('mobileRight').addEventListener('touchstart', () => movePlayer('right'));
344
+ document.getElementById('mobileRight').addEventListener('touchend', () => stopPlayer());
345
+ document.getElementById('mobileUp').addEventListener('touchstart', () => jump());
346
+
347
+ // Menu buttons
348
+ document.getElementById('startBtn').addEventListener('click', startGame);
349
+ document.getElementById('howToBtn').addEventListener('click', () => toggleMenu('howToMenu'));
350
+ document.getElementById('settingsBtn').addEventListener('click', () => toggleMenu('settingsMenu'));
351
+ document.getElementById('backFromHowToBtn').addEventListener('click', () => toggleMenu('mainMenu'));
352
+ document.getElementById('backFromSettingsBtn').addEventListener('click', () => toggleMenu('mainMenu'));
353
+ document.getElementById('restartBtn').addEventListener('click', startGame);
354
+ document.getElementById('menuBtn').addEventListener('click', () => {
355
+ document.getElementById('gameOverMenu').classList.add('hidden');
356
+ document.getElementById('mainMenu').classList.remove('hidden');
357
+ });
358
+
359
+ // Settings buttons
360
+ document.querySelectorAll('.speed-btn').forEach(btn => {
361
+ btn.addEventListener('click', () => {
362
+ document.querySelector('.speed-btn.active').classList.remove('active');
363
+ btn.classList.add('active');
364
+ gameSpeed = parseFloat(btn.dataset.speed);
365
+
366
+ // Update player speed immediately if game is active
367
+ if (gameActive) {
368
+ player.speed = player.speed > 0 ? 3 * gameSpeed : player.speed < 0 ? -3 * gameSpeed : 0;
369
+ }
370
+ });
371
+ });
372
+
373
+ document.querySelectorAll('.trail-btn').forEach(btn => {
374
+ btn.addEventListener('click', () => {
375
+ document.querySelector('.trail-btn.active').classList.remove('active');
376
+ btn.classList.add('active');
377
+ trailStyle = btn.dataset.trail;
378
+ });
379
+ });
380
+
381
+ document.getElementById('soundToggle').addEventListener('change', (e) => {
382
+ soundEnabled = e.target.checked;
383
+ });
384
+ }
385
+
386
+ // Toggle between menus
387
+ function toggleMenu(menuId) {
388
+ document.querySelector('.menu-screen:not(.hidden)').classList.add('hidden');
389
+ document.getElementById(menuId).classList.remove('hidden');
390
+ }
391
+
392
+ // Handle keyboard input
393
+ function handleKeyDown(e) {
394
+ if (!gameActive) return;
395
+
396
+ switch(e.key) {
397
+ case 'ArrowLeft':
398
+ movePlayer('left');
399
+ break;
400
+ case 'ArrowRight':
401
+ movePlayer('right');
402
+ break;
403
+ case 'ArrowUp':
404
+ jump();
405
+ break;
406
+ }
407
+ }
408
+
409
+ function handleKeyUp(e) {
410
+ if (!gameActive) return;
411
+
412
+ if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
413
+ stopPlayer();
414
+ }
415
+ }
416
+
417
+ // Player movement
418
+ function movePlayer(direction) {
419
+ if (direction === 'left') {
420
+ player.speed = -3 * gameSpeed; // Reduced base speed
421
+ } else if (direction === 'right') {
422
+ player.speed = 3 * gameSpeed; // Reduced base speed
423
+ }
424
+ }
425
+
426
+ function stopPlayer() {
427
+ player.speed = 0;
428
+ }
429
+
430
+ function jump() {
431
+ if (!player.isJumping && gameActive) {
432
+ player.velocityY = player.jumpForce;
433
+ player.isJumping = true;
434
+ }
435
+ }
436
+
437
+ // Start the game
438
+ function startGame() {
439
+ // Reset game state
440
+ score = 0;
441
+ trailLength = 1;
442
+ trail = [];
443
+ platforms = [];
444
+ collectibles = [];
445
+ obstacles = [];
446
+
447
+ // Reset player
448
+ player = {
449
+ x: 100,
450
+ y: 300,
451
+ width: 20,
452
+ height: 20,
453
+ velocityY: 0,
454
+ gravity: 0.3,
455
+ jumpForce: -9,
456
+ isJumping: false,
457
+ speed: 0
458
+ };
459
+
460
+ // Generate initial platforms
461
+ generateInitialPlatforms();
462
+
463
+ // Hide menus, show game UI
464
+ document.querySelector('.menu-screen:not(.hidden)').classList.add('hidden');
465
+ document.getElementById('gameUI').classList.remove('hidden');
466
+
467
+ // Start game loop
468
+ gameActive = true;
469
+ requestAnimationFrame(gameLoop);
470
+ }
471
+
472
+ // Generate initial platforms
473
+ function generateInitialPlatforms() {
474
+ // Starting platform
475
+ platforms.push({
476
+ x: 0,
477
+ y: gameHeight - platformHeight,
478
+ width: gameWidth,
479
+ height: platformHeight
480
+ });
481
+
482
+ // Additional platforms - spaced further apart for slower gameplay
483
+ for (let i = 0; i < 10; i++) {
484
+ const width = Math.random() * 150 + 100; // Wider platforms
485
+ const x = i * 400 + 250; // More space between platforms
486
+ const y = gameHeight - platformHeight - (Math.random() * 150); // Lower height variation
487
+
488
+ platforms.push({
489
+ x: x,
490
+ y: y,
491
+ width: width,
492
+ height: platformHeight
493
+ });
494
+
495
+ // Add collectibles above platforms
496
+ if (Math.random() > 0.3) {
497
+ collectibles.push({
498
+ x: x + width / 2 - 10,
499
+ y: y - 30,
500
+ width: 20,
501
+ height: 20,
502
+ collected: false
503
+ });
504
+ }
505
+
506
+ // Add obstacles less frequently
507
+ if (Math.random() > 0.8) {
508
+ obstacles.push({
509
+ x: x + width / 2 - 15,
510
+ y: y - 40,
511
+ width: 30,
512
+ height: 40
513
+ });
514
+ }
515
+ }
516
+ }
517
+
518
+ // Game loop
519
+ function gameLoop() {
520
+ if (!gameActive) return;
521
+
522
+ update();
523
+ render();
524
+
525
+ requestAnimationFrame(gameLoop);
526
+ }
527
+
528
+ // Update game state
529
+ function update() {
530
+ // Update player position
531
+ player.x += player.speed;
532
+
533
+ // Apply gravity
534
+ player.velocityY += player.gravity;
535
+ player.y += player.velocityY;
536
+
537
+ // Check platform collisions
538
+ let onPlatform = false;
539
+ for (const platform of platforms) {
540
+ if (
541
+ player.x + player.width > platform.x &&
542
+ player.x < platform.x + platform.width &&
543
+ player.y + player.height >= platform.y &&
544
+ player.y + player.height <= platform.y + platform.height / 2 &&
545
+ player.velocityY > 0
546
+ ) {
547
+ player.y = platform.y - player.height;
548
+ player.velocityY = 0;
549
+ player.isJumping = false;
550
+ onPlatform = true;
551
+ }
552
+ }
553
+
554
+ // Add current position to trail (less frequently for slower trail growth)
555
+ if (trail.length === 0 ||
556
+ Math.sqrt(
557
+ Math.pow(player.x + player.width / 2 - trail[trail.length-1].x, 2) +
558
+ Math.pow(player.y + player.height / 2 - trail[trail.length-1].y, 2)
559
+ ) > 10) {
560
+ trail.push({
561
+ x: player.x + player.width / 2,
562
+ y: player.y + player.height / 2
563
+ });
564
+ }
565
+
566
+ // Limit trail length
567
+ if (trail.length > maxTrailLength) {
568
+ trail.shift();
569
+ }
570
+
571
+ // Check collectible collisions
572
+ for (const collectible of collectibles) {
573
+ if (
574
+ !collectible.collected &&
575
+ player.x + player.width > collectible.x &&
576
+ player.x < collectible.x + collectible.width &&
577
+ player.y + player.height > collectible.y &&
578
+ player.y < collectible.y + collectible.height
579
+ ) {
580
+ collectible.collected = true;
581
+ score += 10;
582
+ trailLength += 3; // Reduced trail growth
583
+ }
584
+ }
585
+
586
+ // Check obstacle collisions
587
+ for (const obstacle of obstacles) {
588
+ if (
589
+ player.x + player.width > obstacle.x &&
590
+ player.x < obstacle.x + obstacle.width &&
591
+ player.y + player.height > obstacle.y &&
592
+ player.y < obstacle.y + obstacle.height
593
+ ) {
594
+ gameOver();
595
+ return;
596
+ }
597
+ }
598
+
599
+ // Check trail collisions (with more lenient collision detection)
600
+ for (let i = 0; i < trail.length - 15; i++) {
601
+ const segment = trail[i];
602
+ const distance = Math.sqrt(
603
+ Math.pow(player.x + player.width / 2 - segment.x, 2) +
604
+ Math.pow(player.y + player.height / 2 - segment.y, 2)
605
+ );
606
+
607
+ if (distance < 12) { // Slightly more lenient collision
608
+ gameOver();
609
+ return;
610
+ }
611
+ }
612
+
613
+ // Check if player fell off screen
614
+ if (player.y > gameHeight) {
615
+ gameOver();
616
+ return;
617
+ }
618
+
619
+ // Camera follow - move platforms when player reaches right half
620
+ if (player.x > gameWidth / 2) {
621
+ const moveAmount = player.x - gameWidth / 2;
622
+ player.x = gameWidth / 2;
623
+
624
+ // Move platforms and collectibles
625
+ for (const platform of platforms) {
626
+ platform.x -= moveAmount;
627
+ }
628
+
629
+ for (const collectible of collectibles) {
630
+ collectible.x -= moveAmount;
631
+ }
632
+
633
+ for (const obstacle of obstacles) {
634
+ obstacle.x -= moveAmount;
635
+ }
636
+
637
+ // Move trail segments
638
+ for (const segment of trail) {
639
+ segment.x -= moveAmount;
640
+ }
641
+
642
+ // Generate new platforms as needed (with more spacing)
643
+ if (platforms[platforms.length - 1].x < gameWidth) {
644
+ const width = Math.random() * 150 + 100;
645
+ const x = platforms[platforms.length - 1].x + 400;
646
+ const y = gameHeight - platformHeight - (Math.random() * 150);
647
+
648
+ platforms.push({
649
+ x: x,
650
+ y: y,
651
+ width: width,
652
+ height: platformHeight
653
+ });
654
+
655
+ // Add collectibles above platforms
656
+ if (Math.random() > 0.3) {
657
+ collectibles.push({
658
+ x: x + width / 2 - 10,
659
+ y: y - 30,
660
+ width: 20,
661
+ height: 20,
662
+ collected: false
663
+ });
664
+ }
665
+
666
+ // Add obstacles less frequently
667
+ if (Math.random() > 0.8) {
668
+ obstacles.push({
669
+ x: x + width / 2 - 15,
670
+ y: y - 40,
671
+ width: 30,
672
+ height: 40
673
+ });
674
+ }
675
+ }
676
+
677
+ // Remove off-screen platforms
678
+ if (platforms[0].x + platforms[0].width < 0) {
679
+ platforms.shift();
680
+ }
681
+
682
+ // Remove off-screen collectibles
683
+ collectibles = collectibles.filter(c => !c.collected && c.x + c.width > 0);
684
+
685
+ // Remove off-screen obstacles
686
+ obstacles = obstacles.filter(o => o.x + o.width > 0);
687
+ }
688
+
689
+ // Update UI
690
+ document.getElementById('scoreValue').textContent = score;
691
+ document.getElementById('lengthValue').textContent = trailLength;
692
+ }
693
+
694
+ // Render game
695
+ function render() {
696
+ // Clear canvas
697
+ ctx.fillStyle = '#000';
698
+ ctx.fillRect( 0, 0, gameWidth, gameHeight );
699
+
700
+ // Draw background (simple starfield)
701
+ ctx.fillStyle = '#fff';
702
+ for (let i = 0; i < 100; i++) {
703
+ const x = (i * 100 + (Date.now() / 40) % 100) % gameWidth; // Slower star movement
704
+ const y = (i * 80) % gameHeight;
705
+ const size = Math.random() * 2 + 1;
706
+ ctx.fillRect(x, y, size, size);
707
+ }
708
+
709
+ // Draw platforms
710
+ ctx.fillStyle = '#444';
711
+ for (const platform of platforms) {
712
+ ctx.fillRect(platform.x, platform.y, platform.width, platform.height);
713
+
714
+ // Platform details
715
+ ctx.fillStyle = '#555';
716
+ for (let x = platform.x; x < platform.x + platform.width; x += 20) {
717
+ ctx.fillRect(x, platform.y, 15, 3);
718
+ }
719
+ ctx.fillStyle = '#444';
720
+ }
721
+
722
+ // Draw collectibles
723
+ for (const collectible of collectibles) {
724
+ if (!collectible.collected) {
725
+ // Glowing effect
726
+ ctx.beginPath();
727
+ ctx.arc(
728
+ collectible.x + collectible.width / 2,
729
+ collectible.y + collectible.height / 2,
730
+ collectible.width / 2,
731
+ 0,
732
+ Math.PI * 2
733
+ );
734
+
735
+ const gradient = ctx.createRadialGradient(
736
+ collectible.x + collectible.width / 2,
737
+ collectible.y + collectible.height / 2,
738
+ 0,
739
+ collectible.x + collectible.width / 2,
740
+ collectible.y + collectible.height / 2,
741
+ collectible.width / 2
742
+ );
743
+
744
+ gradient.addColorStop(0, 'rgba(255, 255, 0, 0.8)');
745
+ gradient.addColorStop(1, 'rgba(255, 200, 0, 0.2)');
746
+
747
+ ctx.fillStyle = gradient;
748
+ ctx.fill();
749
+
750
+ // Core
751
+ ctx.beginPath();
752
+ ctx.arc(
753
+ collectible.x + collectible.width / 2,
754
+ collectible.y + collectible.height / 2,
755
+ collectible.width / 4,
756
+ 0,
757
+ Math.PI * 2
758
+ );
759
+ ctx.fillStyle = 'yellow';
760
+ ctx.fill();
761
+ }
762
+ }
763
+
764
+ // Draw obstacles
765
+ ctx.fillStyle = '#f00';
766
+ for (const obstacle of obstacles) {
767
+ // Base
768
+ ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);
769
+
770
+ // Spikes
771
+ ctx.beginPath();
772
+ ctx.moveTo(obstacle.x, obstacle.y);
773
+ ctx.lineTo(obstacle.x + obstacle.width / 2, obstacle.y - 15);
774
+ ctx.lineTo(obstacle.x + obstacle.width, obstacle.y);
775
+ ctx.closePath();
776
+ ctx.fillStyle = '#d00';
777
+ ctx.fill();
778
+ }
779
+
780
+ // Draw trail
781
+ if (trail.length > 1) {
782
+ ctx.beginPath();
783
+ ctx.moveTo(trail[0].x, trail[0].y);
784
+
785
+ for (let i = 1; i < trail.length; i++) {
786
+ ctx.lineTo(trail[i].x, trail[i].y);
787
+ }
788
+
789
+ ctx.lineWidth = 8;
790
+
791
+ switch(trailStyle) {
792
+ case 'glow':
793
+ ctx.strokeStyle = 'rgba(0, 247, 255, 0.7)';
794
+ ctx.shadowBlur = 15;
795
+ ctx.shadowColor = '#00f7ff';
796
+ break;
797
+ case 'pulse':
798
+ const pulseVal = Math.sin(Date.now() / 300) * 0.3 + 0.7; // Slower pulse
799
+ ctx.strokeStyle = `rgba(0, ${Math.floor(247 * pulseVal)}, 255, ${pulseVal})`;
800
+ break;
801
+ case 'rainbow':
802
+ const gradient = ctx.createLinearGradient(0, 0, gameWidth, 0);
803
+ gradient.addColorStop(0, '#ff00f7');
804
+ gradient.addColorStop(0.5, '#00f7ff');
805
+ gradient.addColorStop(1, '#9d00ff');
806
+ ctx.strokeStyle = gradient;
807
+ break;
808
+ default: // solid
809
+ ctx.strokeStyle = '#00f7ff';
810
+ }
811
+
812
+ ctx.stroke();
813
+
814
+ // Reset shadow
815
+ ctx.shadowBlur = 0;
816
+ }
817
+
818
+ // Draw player
819
+ ctx.fillStyle = '#fff';
820
+ ctx.fillRect(player.x, player.y, player.width, player.height);
821
+
822
+ // Player eyes
823
+ ctx.fillStyle = '#00f7ff';
824
+ ctx.fillRect(player.x + 5, player.y + 5, 5, 5);
825
+ ctx.fillRect(player.x + 10, player.y + 5, 5, 5);
826
+ }
827
+
828
+ // Game over
829
+ function gameOver() {
830
+ gameActive = false;
831
+
832
+ // Show game over menu
833
+ document.getElementById('gameUI').classList.add('hidden');
834
+ document.getElementById('gameOverMenu').classList.remove('hidden');
835
+ document.getElementById('finalScore').textContent = score;
836
+ }
837
+
838
+ // Initialize game when page loads
839
+ window.addEventListener('load', init);
840
+ </script>
841
+ <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=sreeramajay/pixel-rush" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
842
+ </html>