yunfengnobug commited on
Commit
7c165c4
·
verified ·
1 Parent(s): 276646f

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +572 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Yf
3
- emoji: 🦀
4
- colorFrom: pink
5
- colorTo: red
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: yf
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: gray
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,572 @@
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>Advanced Snake Game</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
+ @keyframes pulse {
11
+ 0%, 100% { transform: scale(1); }
12
+ 50% { transform: scale(1.2); }
13
+ }
14
+ .pulse-animation {
15
+ animation: pulse 1s infinite;
16
+ }
17
+ .blink-animation {
18
+ animation: blink 0.5s infinite alternate;
19
+ }
20
+ @keyframes blink {
21
+ from { opacity: 1; }
22
+ to { opacity: 0.5; }
23
+ }
24
+ #gameCanvas {
25
+ border: 3px solid #4a5568;
26
+ border-radius: 8px;
27
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
28
+ }
29
+ .food-icon {
30
+ font-size: 12px;
31
+ position: absolute;
32
+ transform: translate(-50%, -50%);
33
+ }
34
+ </style>
35
+ </head>
36
+ <body class="bg-gray-900 text-white min-h-screen flex flex-col items-center justify-center p-4">
37
+ <div class="text-center mb-6">
38
+ <h1 class="text-4xl font-bold mb-2 text-green-400">Advanced Snake Game</h1>
39
+ <p class="text-gray-300 mb-4">Eat different foods for special effects!</p>
40
+
41
+ <div class="flex justify-center gap-8 mb-6">
42
+ <div class="flex items-center">
43
+ <div class="w-4 h-4 bg-green-500 rounded-full mr-2"></div>
44
+ <span>Normal (+1)</span>
45
+ </div>
46
+ <div class="flex items-center">
47
+ <div class="w-4 h-4 bg-yellow-400 rounded-full mr-2 pulse-animation"></div>
48
+ <span>Bonus (+3)</span>
49
+ </div>
50
+ <div class="flex items-center">
51
+ <div class="w-4 h-4 bg-red-500 rounded-full mr-2 blink-animation"></div>
52
+ <span>Poison (-2)</span>
53
+ </div>
54
+ <div class="flex items-center">
55
+ <div class="w-4 h-4 bg-blue-400 rounded-full mr-2"></div>
56
+ <span>Speed Up (2x)</span>
57
+ </div>
58
+ <div class="flex items-center">
59
+ <div class="w-4 h-4 bg-purple-500 rounded-full mr-2"></div>
60
+ <span>Slow Down (0.5x)</span>
61
+ </div>
62
+ </div>
63
+
64
+ <div class="flex justify-center gap-4 mb-4">
65
+ <div class="bg-gray-800 px-4 py-2 rounded-lg">
66
+ <span class="text-gray-400">Score:</span>
67
+ <span id="score" class="text-xl font-bold ml-2">0</span>
68
+ </div>
69
+ <div class="bg-gray-800 px-4 py-2 rounded-lg">
70
+ <span class="text-gray-400">High Score:</span>
71
+ <span id="highScore" class="text-xl font-bold ml-2">0</span>
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ <canvas id="gameCanvas" width="400" height="400" class="bg-gray-800"></canvas>
77
+
78
+ <div class="mt-6 flex gap-4">
79
+ <button id="startBtn" class="bg-green-600 hover:bg-green-700 px-6 py-2 rounded-lg font-bold transition">
80
+ <i class="fas fa-play mr-2"></i>Start Game
81
+ </button>
82
+ <button id="pauseBtn" class="bg-yellow-600 hover:bg-yellow-700 px-6 py-2 rounded-lg font-bold transition" disabled>
83
+ <i class="fas fa-pause mr-2"></i>Pause
84
+ </button>
85
+ <button id="restartBtn" class="bg-red-600 hover:bg-red-700 px-6 py-2 rounded-lg font-bold transition">
86
+ <i class="fas fa-redo mr-2"></i>Restart
87
+ </button>
88
+ </div>
89
+
90
+ <div class="mt-6 bg-gray-800 p-4 rounded-lg max-w-md">
91
+ <h2 class="text-xl font-bold mb-2 text-green-400">How to Play</h2>
92
+ <ul class="text-left space-y-2 text-gray-300">
93
+ <li><i class="fas fa-arrow-up mr-2"></i>Use arrow keys or swipe to move</li>
94
+ <li><i class="fas fa-apple-alt mr-2 text-green-500"></i>Green food: +1 point</li>
95
+ <li><i class="fas fa-star mr-2 text-yellow-400"></i>Yellow food: +3 points</li>
96
+ <li><i class="fas fa-skull-crossbones mr-2 text-red-500"></i>Red food: -2 points</li>
97
+ <li><i class="fas fa-bolt mr-2 text-blue-400"></i>Blue food: Double speed for 5 sec</li>
98
+ <li><i class="fas fa-hourglass-half mr-2 text-purple-500"></i>Purple food: Half speed for 5 sec</li>
99
+ <li>Avoid walls and yourself!</li>
100
+ </ul>
101
+ </div>
102
+
103
+ <script>
104
+ document.addEventListener('DOMContentLoaded', () => {
105
+ const canvas = document.getElementById('gameCanvas');
106
+ const ctx = canvas.getContext('2d');
107
+ const scoreElement = document.getElementById('score');
108
+ const highScoreElement = document.getElementById('highScore');
109
+ const startBtn = document.getElementById('startBtn');
110
+ const pauseBtn = document.getElementById('pauseBtn');
111
+ const restartBtn = document.getElementById('restartBtn');
112
+
113
+ // Game settings
114
+ const gridSize = 20;
115
+ const tileCount = canvas.width / gridSize;
116
+ let speed = 7;
117
+ let baseSpeed = 7;
118
+ let score = 0;
119
+ let highScore = localStorage.getItem('snakeHighScore') || 0;
120
+ let gameRunning = false;
121
+ let gamePaused = false;
122
+ let speedEffectActive = false;
123
+ let speedEffectEndTime = 0;
124
+
125
+ // Snake
126
+ let snake = [];
127
+ let snakeLength = 5;
128
+ let xVelocity = 0;
129
+ let yVelocity = 0;
130
+ let nextXVelocity = 0;
131
+ let nextYVelocity = 0;
132
+
133
+ // Food types
134
+ const FOOD_TYPES = {
135
+ NORMAL: { color: '#48BB78', points: 1, effect: null, icon: 'apple-alt' },
136
+ BONUS: { color: '#ECC94B', points: 3, effect: null, icon: 'star', spawnChance: 0.15 },
137
+ POISON: { color: '#F56565', points: -2, effect: null, icon: 'skull-crossbones', spawnChance: 0.1 },
138
+ SPEED_UP: { color: '#4299E1', points: 0, effect: 'speedUp', icon: 'bolt', spawnChance: 0.1 },
139
+ SPEED_DOWN: { color: '#9F7AEA', points: 0, effect: 'speedDown', icon: 'hourglass-half', spawnChance: 0.1 }
140
+ };
141
+
142
+ let food = { x: 0, y: 0, type: FOOD_TYPES.NORMAL };
143
+
144
+ // Initialize game
145
+ function initGame() {
146
+ snake = [];
147
+ for (let i = snakeLength - 1; i >= 0; i--) {
148
+ snake.push({ x: i, y: 0 });
149
+ }
150
+
151
+ xVelocity = 1;
152
+ yVelocity = 0;
153
+ nextXVelocity = 1;
154
+ nextYVelocity = 0;
155
+
156
+ score = 0;
157
+ speed = baseSpeed;
158
+ speedEffectActive = false;
159
+
160
+ spawnFood();
161
+ updateScore();
162
+ }
163
+
164
+ // Game loop
165
+ function gameLoop() {
166
+ if (!gameRunning || gamePaused) return;
167
+
168
+ setTimeout(() => {
169
+ if (speedEffectActive && Date.now() > speedEffectEndTime) {
170
+ speed = baseSpeed;
171
+ speedEffectActive = false;
172
+ }
173
+
174
+ if (checkCollision()) {
175
+ gameOver();
176
+ return;
177
+ }
178
+
179
+ moveSnake();
180
+
181
+ if (eatFood()) {
182
+ handleFoodEffect();
183
+ spawnFood();
184
+ }
185
+
186
+ drawGame();
187
+ gameLoop();
188
+ }, 1000 / speed);
189
+ }
190
+
191
+ // Move snake
192
+ function moveSnake() {
193
+ xVelocity = nextXVelocity;
194
+ yVelocity = nextYVelocity;
195
+
196
+ const head = { x: snake[0].x + xVelocity, y: snake[0].y + yVelocity };
197
+
198
+ snake.unshift(head);
199
+
200
+ if (snake.length > snakeLength) {
201
+ snake.pop();
202
+ }
203
+ }
204
+
205
+ // Check collision
206
+ function checkCollision() {
207
+ const head = snake[0];
208
+
209
+ // Wall collision
210
+ if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
211
+ return true;
212
+ }
213
+
214
+ // Self collision
215
+ for (let i = 1; i < snake.length; i++) {
216
+ if (head.x === snake[i].x && head.y === snake[i].y) {
217
+ return true;
218
+ }
219
+ }
220
+
221
+ return false;
222
+ }
223
+
224
+ // Spawn food
225
+ function spawnFood() {
226
+ // Determine food type based on spawn chances
227
+ const rand = Math.random();
228
+ let foodType = FOOD_TYPES.NORMAL;
229
+
230
+ if (rand < 0.1) {
231
+ foodType = FOOD_TYPES.POISON;
232
+ } else if (rand < 0.25) {
233
+ foodType = FOOD_TYPES.BONUS;
234
+ } else if (rand < 0.35) {
235
+ foodType = FOOD_TYPES.SPEED_UP;
236
+ } else if (rand < 0.45) {
237
+ foodType = FOOD_TYPES.SPEED_DOWN;
238
+ }
239
+
240
+ // Find empty position
241
+ let positionFound = false;
242
+ while (!positionFound) {
243
+ food.x = Math.floor(Math.random() * tileCount);
244
+ food.y = Math.floor(Math.random() * tileCount);
245
+
246
+ positionFound = true;
247
+ for (let i = 0; i < snake.length; i++) {
248
+ if (snake[i].x === food.x && snake[i].y === food.y) {
249
+ positionFound = false;
250
+ break;
251
+ }
252
+ }
253
+ }
254
+
255
+ food.type = foodType;
256
+ }
257
+
258
+ // Check if snake ate food
259
+ function eatFood() {
260
+ const head = snake[0];
261
+ if (head.x === food.x && head.y === food.y) {
262
+ score += food.type.points;
263
+ snakeLength += Math.max(1, Math.floor(food.type.points / 2)); // Grow more for bonus food
264
+ updateScore();
265
+ return true;
266
+ }
267
+ return false;
268
+ }
269
+
270
+ // Handle food effects
271
+ function handleFoodEffect() {
272
+ if (food.type.effect === 'speedUp') {
273
+ speed = baseSpeed * 2;
274
+ speedEffectActive = true;
275
+ speedEffectEndTime = Date.now() + 5000;
276
+ showEffectMessage('Speed Boost!', '#4299E1');
277
+ } else if (food.type.effect === 'speedDown') {
278
+ speed = baseSpeed * 0.5;
279
+ speedEffectActive = true;
280
+ speedEffectEndTime = Date.now() + 5000;
281
+ showEffectMessage('Slowed Down!', '#9F7AEA');
282
+ }
283
+ }
284
+
285
+ // Show effect message
286
+ function showEffectMessage(text, color) {
287
+ const effectDiv = document.createElement('div');
288
+ effectDiv.textContent = text;
289
+ effectDiv.className = 'absolute text-xl font-bold animate-bounce';
290
+ effectDiv.style.color = color;
291
+ effectDiv.style.left = `${food.x * gridSize + gridSize / 2}px`;
292
+ effectDiv.style.top = `${food.y * gridSize + gridSize / 2}px`;
293
+ effectDiv.style.transform = 'translate(-50%, -50%)';
294
+
295
+ canvas.parentNode.appendChild(effectDiv);
296
+
297
+ setTimeout(() => {
298
+ effectDiv.remove();
299
+ }, 1000);
300
+ }
301
+
302
+ // Update score display
303
+ function updateScore() {
304
+ scoreElement.textContent = score;
305
+ if (score > highScore) {
306
+ highScore = score;
307
+ localStorage.setItem('snakeHighScore', highScore);
308
+ highScoreElement.textContent = highScore;
309
+ }
310
+ }
311
+
312
+ // Draw game
313
+ function drawGame() {
314
+ // Clear canvas
315
+ ctx.fillStyle = '#1a202c';
316
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
317
+
318
+ // Draw grid
319
+ ctx.strokeStyle = '#2d3748';
320
+ ctx.lineWidth = 0.5;
321
+ for (let i = 0; i < tileCount; i++) {
322
+ ctx.beginPath();
323
+ ctx.moveTo(i * gridSize, 0);
324
+ ctx.lineTo(i * gridSize, canvas.height);
325
+ ctx.stroke();
326
+
327
+ ctx.beginPath();
328
+ ctx.moveTo(0, i * gridSize);
329
+ ctx.lineTo(canvas.width, i * gridSize);
330
+ ctx.stroke();
331
+ }
332
+
333
+ // Draw snake
334
+ snake.forEach((segment, index) => {
335
+ // Head is different color
336
+ if (index === 0) {
337
+ ctx.fillStyle = '#38a169';
338
+ } else {
339
+ // Gradient body
340
+ const intensity = 1 - (index / snake.length) * 0.7;
341
+ ctx.fillStyle = `rgb(56, 161, ${Math.floor(105 * intensity)})`;
342
+ }
343
+
344
+ ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize - 1, gridSize - 1);
345
+
346
+ // Add eyes to head
347
+ if (index === 0) {
348
+ ctx.fillStyle = 'white';
349
+
350
+ // Eye positions based on direction
351
+ let leftEyeX, leftEyeY, rightEyeX, rightEyeY;
352
+
353
+ if (xVelocity === 1) { // Right
354
+ leftEyeX = segment.x * gridSize + gridSize - 5;
355
+ leftEyeY = segment.y * gridSize + 5;
356
+ rightEyeX = segment.x * gridSize + gridSize - 5;
357
+ rightEyeY = segment.y * gridSize + gridSize - 5;
358
+ } else if (xVelocity === -1) { // Left
359
+ leftEyeX = segment.x * gridSize + 5;
360
+ leftEyeY = segment.y * gridSize + 5;
361
+ rightEyeX = segment.x * gridSize + 5;
362
+ rightEyeY = segment.y * gridSize + gridSize - 5;
363
+ } else if (yVelocity === 1) { // Down
364
+ leftEyeX = segment.x * gridSize + 5;
365
+ leftEyeY = segment.y * gridSize + gridSize - 5;
366
+ rightEyeX = segment.x * gridSize + gridSize - 5;
367
+ rightEyeY = segment.y * gridSize + gridSize - 5;
368
+ } else { // Up
369
+ leftEyeX = segment.x * gridSize + 5;
370
+ leftEyeY = segment.y * gridSize + 5;
371
+ rightEyeX = segment.x * gridSize + gridSize - 5;
372
+ rightEyeY = segment.y * gridSize + 5;
373
+ }
374
+
375
+ ctx.beginPath();
376
+ ctx.arc(leftEyeX, leftEyeY, 2, 0, Math.PI * 2);
377
+ ctx.fill();
378
+
379
+ ctx.beginPath();
380
+ ctx.arc(rightEyeX, rightEyeY, 2, 0, Math.PI * 2);
381
+ ctx.fill();
382
+ }
383
+ });
384
+
385
+ // Draw food
386
+ ctx.fillStyle = food.type.color;
387
+ ctx.beginPath();
388
+ ctx.arc(
389
+ food.x * gridSize + gridSize / 2,
390
+ food.y * gridSize + gridSize / 2,
391
+ gridSize / 2 - 1,
392
+ 0,
393
+ Math.PI * 2
394
+ );
395
+ ctx.fill();
396
+
397
+ // Add food icon
398
+ const icon = document.createElement('i');
399
+ icon.className = `fas fa-${food.type.icon} food-icon`;
400
+ icon.style.color = food.type.color === '#F56565' ? 'white' : 'black';
401
+ icon.style.left = `${food.x * gridSize + gridSize / 2}px`;
402
+ icon.style.top = `${food.y * gridSize + gridSize / 2}px`;
403
+
404
+ // Clear previous food icon
405
+ const oldIcons = document.querySelectorAll('.food-icon');
406
+ oldIcons.forEach(icon => icon.remove());
407
+
408
+ canvas.parentNode.appendChild(icon);
409
+
410
+ // Draw speed effect indicator
411
+ if (speedEffectActive) {
412
+ ctx.fillStyle = speed > baseSpeed ? '#4299E1' : '#9F7AEA';
413
+ ctx.font = '12px Arial';
414
+ ctx.fillText(
415
+ speed > baseSpeed ? '2x SPEED' : '0.5x SPEED',
416
+ 10,
417
+ canvas.height - 10
418
+ );
419
+
420
+ // Draw timer bar
421
+ const timeLeft = speedEffectEndTime - Date.now();
422
+ const percentage = Math.max(0, timeLeft / 5000);
423
+
424
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
425
+ ctx.fillRect(canvas.width - 110, canvas.height - 20, 100, 10);
426
+
427
+ ctx.fillStyle = speed > baseSpeed ? '#4299E1' : '#9F7AEA';
428
+ ctx.fillRect(canvas.width - 110, canvas.height - 20, 100 * percentage, 10);
429
+ }
430
+ }
431
+
432
+ // Game over
433
+ function gameOver() {
434
+ gameRunning = false;
435
+ startBtn.disabled = false;
436
+ pauseBtn.disabled = true;
437
+
438
+ // Show game over message
439
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
440
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
441
+
442
+ ctx.fillStyle = 'white';
443
+ ctx.font = '30px Arial';
444
+ ctx.textAlign = 'center';
445
+ ctx.fillText('GAME OVER', canvas.width / 2, canvas.height / 2 - 30);
446
+
447
+ ctx.font = '20px Arial';
448
+ ctx.fillText(`Score: ${score}`, canvas.width / 2, canvas.height / 2 + 10);
449
+
450
+ if (score === highScore) {
451
+ ctx.fillStyle = '#ECC94B';
452
+ ctx.fillText('NEW HIGH SCORE!', canvas.width / 2, canvas.height / 2 + 40);
453
+ }
454
+ }
455
+
456
+ // Event listeners
457
+ startBtn.addEventListener('click', () => {
458
+ if (!gameRunning) {
459
+ initGame();
460
+ gameRunning = true;
461
+ gamePaused = false;
462
+ startBtn.disabled = true;
463
+ pauseBtn.disabled = false;
464
+ gameLoop();
465
+ }
466
+ });
467
+
468
+ pauseBtn.addEventListener('click', () => {
469
+ if (gameRunning) {
470
+ gamePaused = !gamePaused;
471
+ pauseBtn.innerHTML = gamePaused
472
+ ? '<i class="fas fa-play mr-2"></i>Resume'
473
+ : '<i class="fas fa-pause mr-2"></i>Pause';
474
+
475
+ if (!gamePaused) {
476
+ gameLoop();
477
+ }
478
+ }
479
+ });
480
+
481
+ restartBtn.addEventListener('click', () => {
482
+ gameRunning = false;
483
+ initGame();
484
+ gameRunning = true;
485
+ gamePaused = false;
486
+ startBtn.disabled = true;
487
+ pauseBtn.disabled = false;
488
+ pauseBtn.innerHTML = '<i class="fas fa-pause mr-2"></i>Pause';
489
+ gameLoop();
490
+ });
491
+
492
+ // Keyboard controls
493
+ document.addEventListener('keydown', (e) => {
494
+ if (!gameRunning || gamePaused) return;
495
+
496
+ // Prevent reverse direction
497
+ switch (e.key) {
498
+ case 'ArrowUp':
499
+ if (yVelocity !== 1) {
500
+ nextXVelocity = 0;
501
+ nextYVelocity = -1;
502
+ }
503
+ break;
504
+ case 'ArrowDown':
505
+ if (yVelocity !== -1) {
506
+ nextXVelocity = 0;
507
+ nextYVelocity = 1;
508
+ }
509
+ break;
510
+ case 'ArrowLeft':
511
+ if (xVelocity !== 1) {
512
+ nextXVelocity = -1;
513
+ nextYVelocity = 0;
514
+ }
515
+ break;
516
+ case 'ArrowRight':
517
+ if (xVelocity !== -1) {
518
+ nextXVelocity = 1;
519
+ nextYVelocity = 0;
520
+ }
521
+ break;
522
+ }
523
+ });
524
+
525
+ // Touch controls for mobile
526
+ let touchStartX = 0;
527
+ let touchStartY = 0;
528
+
529
+ canvas.addEventListener('touchstart', (e) => {
530
+ if (!gameRunning || gamePaused) return;
531
+ touchStartX = e.touches[0].clientX;
532
+ touchStartY = e.touches[0].clientY;
533
+ }, false);
534
+
535
+ canvas.addEventListener('touchmove', (e) => {
536
+ if (!gameRunning || gamePaused) return;
537
+ e.preventDefault();
538
+
539
+ const touchEndX = e.touches[0].clientX;
540
+ const touchEndY = e.touches[0].clientY;
541
+
542
+ const dx = touchEndX - touchStartX;
543
+ const dy = touchEndY - touchStartY;
544
+
545
+ // Determine primary direction
546
+ if (Math.abs(dx) > Math.abs(dy)) {
547
+ // Horizontal swipe
548
+ if (dx > 0 && xVelocity !== -1) {
549
+ nextXVelocity = 1;
550
+ nextYVelocity = 0;
551
+ } else if (dx < 0 && xVelocity !== 1) {
552
+ nextXVelocity = -1;
553
+ nextYVelocity = 0;
554
+ }
555
+ } else {
556
+ // Vertical swipe
557
+ if (dy > 0 && yVelocity !== -1) {
558
+ nextXVelocity = 0;
559
+ nextYVelocity = 1;
560
+ } else if (dy < 0 && yVelocity !== 1) {
561
+ nextXVelocity = 0;
562
+ nextYVelocity = -1;
563
+ }
564
+ }
565
+ }, false);
566
+
567
+ // Initialize high score display
568
+ highScoreElement.textContent = highScore;
569
+ });
570
+ </script>
571
+ <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=yunfengnobug/yf" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body>
572
+ </html>