pijou commited on
Commit
33133ef
·
verified ·
1 Parent(s): 2ac949e

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +365 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Snake
3
- emoji:
4
- colorFrom: indigo
5
- colorTo: indigo
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: snake
3
+ emoji: 🐳
4
+ colorFrom: yellow
5
+ colorTo: pink
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,365 @@
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>Neon Snake Game</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <style>
9
+ @import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
10
+
11
+ body {
12
+ font-family: 'Press Start 2P', cursive;
13
+ background-color: #0f172a;
14
+ overflow: hidden;
15
+ }
16
+
17
+ #gameCanvas {
18
+ box-shadow: 0 0 20px #3b82f6;
19
+ border-radius: 8px;
20
+ }
21
+
22
+ .neon-text {
23
+ text-shadow: 0 0 5px #3b82f6, 0 0 10px #3b82f6, 0 0 15px #3b82f6;
24
+ }
25
+
26
+ .neon-button {
27
+ transition: all 0.3s;
28
+ box-shadow: 0 0 10px #3b82f6;
29
+ }
30
+
31
+ .neon-button:hover {
32
+ box-shadow: 0 0 20px #3b82f6, 0 0 30px #3b82f6;
33
+ transform: translateY(-2px);
34
+ }
35
+
36
+ .snake-cell {
37
+ border-radius: 3px;
38
+ transition: all 0.1s;
39
+ }
40
+
41
+ .pulse {
42
+ animation: pulse 1.5s infinite;
43
+ }
44
+
45
+ @keyframes pulse {
46
+ 0% { opacity: 0.7; }
47
+ 50% { opacity: 1; }
48
+ 100% { opacity: 0.7; }
49
+ }
50
+ </style>
51
+ </head>
52
+ <body class="min-h-screen flex flex-col items-center justify-center p-4">
53
+ <div class="text-center mb-8">
54
+ <h1 class="text-4xl md:text-5xl font-bold text-blue-400 neon-text mb-4">NEON SNAKE</h1>
55
+ <div class="flex justify-center gap-8 text-blue-300 mb-6">
56
+ <div>
57
+ <p class="text-sm">SCORE</p>
58
+ <p id="score" class="text-2xl">0</p>
59
+ </div>
60
+ <div>
61
+ <p class="text-sm">HIGH SCORE</p>
62
+ <p id="highScore" class="text-2xl">0</p>
63
+ </div>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="relative">
68
+ <canvas id="gameCanvas" width="400" height="400" class="bg-gray-900 border-2 border-blue-500"></canvas>
69
+
70
+ <div id="gameOver" class="hidden absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 rounded">
71
+ <h2 class="text-red-500 text-3xl mb-6 neon-text">GAME OVER!</h2>
72
+ <p class="text-blue-300 mb-8">Your score: <span id="finalScore" class="text-white">0</span></p>
73
+ <button id="restartButton" class="px-6 py-3 bg-blue-600 text-white rounded-full neon-button font-bold">
74
+ PLAY AGAIN
75
+ </button>
76
+ </div>
77
+
78
+ <div id="startScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-80 rounded">
79
+ <h2 class="text-blue-400 text-3xl mb-6 neon-text pulse">NEON SNAKE</h2>
80
+ <p class="text-blue-300 mb-8 text-center px-4">Use arrow keys or swipe to control the snake</p>
81
+ <button id="startButton" class="px-6 py-3 bg-blue-600 text-white rounded-full neon-button font-bold">
82
+ START GAME
83
+ </button>
84
+ </div>
85
+ </div>
86
+
87
+ <div class="mt-8 text-blue-300 text-sm text-center">
88
+ <p>Controls: Arrow Keys or Swipe</p>
89
+ <p class="mt-2">Eat the food (●) to grow longer!</p>
90
+ </div>
91
+
92
+ <script>
93
+ document.addEventListener('DOMContentLoaded', () => {
94
+ const canvas = document.getElementById('gameCanvas');
95
+ const ctx = canvas.getContext('2d');
96
+ const scoreElement = document.getElementById('score');
97
+ const highScoreElement = document.getElementById('highScore');
98
+ const finalScoreElement = document.getElementById('finalScore');
99
+ const gameOverScreen = document.getElementById('gameOver');
100
+ const startScreen = document.getElementById('startScreen');
101
+ const startButton = document.getElementById('startButton');
102
+ const restartButton = document.getElementById('restartButton');
103
+
104
+ // Game settings
105
+ const gridSize = 20;
106
+ const tileCount = canvas.width / gridSize;
107
+ let speed = 7;
108
+
109
+ // Game state
110
+ let snake = [{x: 10, y: 10}];
111
+ let food = {x: 5, y: 5};
112
+ let direction = {x: 0, y: 0};
113
+ let nextDirection = {x: 0, y: 0};
114
+ let score = 0;
115
+ let highScore = localStorage.getItem('snakeHighScore') || 0;
116
+ let gameRunning = false;
117
+ let gameLoop;
118
+ let touchStartX = 0;
119
+ let touchStartY = 0;
120
+
121
+ highScoreElement.textContent = highScore;
122
+
123
+ // Draw functions
124
+ function drawSnake() {
125
+ snake.forEach((segment, index) => {
126
+ // Head is a different color
127
+ if (index === 0) {
128
+ ctx.fillStyle = '#3b82f6';
129
+ } else {
130
+ // Body segments get progressively darker
131
+ const intensity = 200 - Math.min(190, index * 5);
132
+ ctx.fillStyle = `rgb(59, 130, ${intensity})`;
133
+ }
134
+
135
+ ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
136
+
137
+ // Add a subtle glow effect
138
+ if (index === 0) {
139
+ ctx.shadowColor = '#3b82f6';
140
+ ctx.shadowBlur = 10;
141
+ ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
142
+ ctx.shadowBlur = 0;
143
+ }
144
+ });
145
+ }
146
+
147
+ function drawFood() {
148
+ ctx.fillStyle = '#ef4444';
149
+ ctx.beginPath();
150
+ const centerX = food.x * gridSize + gridSize / 2;
151
+ const centerY = food.y * gridSize + gridSize / 2;
152
+ const radius = gridSize / 2;
153
+ ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
154
+ ctx.fill();
155
+
156
+ // Add glow effect
157
+ ctx.shadowColor = '#ef4444';
158
+ ctx.shadowBlur = 15;
159
+ ctx.fill();
160
+ ctx.shadowBlur = 0;
161
+
162
+ // Add inner circle for depth
163
+ ctx.fillStyle = '#fca5a5';
164
+ ctx.beginPath();
165
+ ctx.arc(centerX, centerY, radius / 2, 0, Math.PI * 2);
166
+ ctx.fill();
167
+ }
168
+
169
+ function drawGrid() {
170
+ ctx.strokeStyle = '#1e293b';
171
+ ctx.lineWidth = 0.5;
172
+
173
+ for (let i = 0; i < tileCount; i++) {
174
+ // Vertical lines
175
+ ctx.beginPath();
176
+ ctx.moveTo(i * gridSize, 0);
177
+ ctx.lineTo(i * gridSize, canvas.height);
178
+ ctx.stroke();
179
+
180
+ // Horizontal lines
181
+ ctx.beginPath();
182
+ ctx.moveTo(0, i * gridSize);
183
+ ctx.lineTo(canvas.width, i * gridSize);
184
+ ctx.stroke();
185
+ }
186
+ }
187
+
188
+ // Game logic
189
+ function update() {
190
+ // Update direction from the next direction buffer
191
+ direction = {...nextDirection};
192
+
193
+ // Move snake
194
+ const head = {x: snake[0].x + direction.x, y: snake[0].y + direction.y};
195
+
196
+ // Check wall collision
197
+ if (head.x < 0 || head.x >= tileCount || head.y < 0 || head.y >= tileCount) {
198
+ gameOver();
199
+ return;
200
+ }
201
+
202
+ // Check self collision
203
+ for (let i = 1; i < snake.length; i++) {
204
+ if (head.x === snake[i].x && head.y === snake[i].y) {
205
+ gameOver();
206
+ return;
207
+ }
208
+ }
209
+
210
+ // Add new head
211
+ snake.unshift(head);
212
+
213
+ // Check food collision
214
+ if (head.x === food.x && head.y === food.y) {
215
+ // Increase score
216
+ score += 10;
217
+ scoreElement.textContent = score;
218
+
219
+ // Generate new food (not on snake)
220
+ generateFood();
221
+
222
+ // Increase speed slightly every 50 points
223
+ if (score % 50 === 0 && speed < 15) {
224
+ speed += 0.5;
225
+ }
226
+ } else {
227
+ // Remove tail if no food eaten
228
+ snake.pop();
229
+ }
230
+ }
231
+
232
+ function generateFood() {
233
+ let validPosition = false;
234
+
235
+ while (!validPosition) {
236
+ food = {
237
+ x: Math.floor(Math.random() * tileCount),
238
+ y: Math.floor(Math.random() * tileCount)
239
+ };
240
+
241
+ // Check if food is on snake
242
+ validPosition = true;
243
+ for (let segment of snake) {
244
+ if (segment.x === food.x && segment.y === food.y) {
245
+ validPosition = false;
246
+ break;
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ function gameOver() {
253
+ clearInterval(gameLoop);
254
+ gameRunning = false;
255
+
256
+ // Update high score
257
+ if (score > highScore) {
258
+ highScore = score;
259
+ localStorage.setItem('snakeHighScore', highScore);
260
+ highScoreElement.textContent = highScore;
261
+ }
262
+
263
+ finalScoreElement.textContent = score;
264
+ gameOverScreen.classList.remove('hidden');
265
+ }
266
+
267
+ function resetGame() {
268
+ snake = [{x: 10, y: 10}];
269
+ direction = {x: 0, y: 0};
270
+ nextDirection = {x: 0, y: 0};
271
+ score = 0;
272
+ scoreElement.textContent = score;
273
+ speed = 7;
274
+ generateFood();
275
+ gameOverScreen.classList.add('hidden');
276
+ }
277
+
278
+ function startGame() {
279
+ resetGame();
280
+ startScreen.classList.add('hidden');
281
+ gameRunning = true;
282
+
283
+ gameLoop = setInterval(() => {
284
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
285
+ drawGrid();
286
+ drawFood();
287
+ drawSnake();
288
+ update();
289
+ }, 1000 / speed);
290
+ }
291
+
292
+ // Event listeners
293
+ document.addEventListener('keydown', (e) => {
294
+ if (!gameRunning && (e.key === ' ' || e.key === 'Enter')) {
295
+ startGame();
296
+ return;
297
+ }
298
+
299
+ // Prevent reverse direction
300
+ switch (e.key) {
301
+ case 'ArrowUp':
302
+ if (direction.y === 0) nextDirection = {x: 0, y: -1};
303
+ break;
304
+ case 'ArrowDown':
305
+ if (direction.y === 0) nextDirection = {x: 0, y: 1};
306
+ break;
307
+ case 'ArrowLeft':
308
+ if (direction.x === 0) nextDirection = {x: -1, y: 0};
309
+ break;
310
+ case 'ArrowRight':
311
+ if (direction.x === 0) nextDirection = {x: 1, y: 0};
312
+ break;
313
+ }
314
+ });
315
+
316
+ // Touch controls for mobile
317
+ canvas.addEventListener('touchstart', (e) => {
318
+ touchStartX = e.touches[0].clientX;
319
+ touchStartY = e.touches[0].clientY;
320
+ }, false);
321
+
322
+ canvas.addEventListener('touchmove', (e) => {
323
+ if (!touchStartX || !touchStartY || !gameRunning) return;
324
+
325
+ const touchEndX = e.touches[0].clientX;
326
+ const touchEndY = e.touches[0].clientY;
327
+
328
+ const diffX = touchStartX - touchEndX;
329
+ const diffY = touchStartY - touchEndY;
330
+
331
+ // Determine swipe direction
332
+ if (Math.abs(diffX) > Math.abs(diffY)) {
333
+ // Horizontal swipe
334
+ if (diffX > 0 && direction.x === 0) {
335
+ nextDirection = {x: -1, y: 0}; // Left swipe
336
+ } else if (diffX < 0 && direction.x === 0) {
337
+ nextDirection = {x: 1, y: 0}; // Right swipe
338
+ }
339
+ } else {
340
+ // Vertical swipe
341
+ if (diffY > 0 && direction.y === 0) {
342
+ nextDirection = {x: 0, y: -1}; // Up swipe
343
+ } else if (diffY < 0 && direction.y === 0) {
344
+ nextDirection = {x: 0, y: 1}; // Down swipe
345
+ }
346
+ }
347
+
348
+ // Reset touch coordinates
349
+ touchStartX = 0;
350
+ touchStartY = 0;
351
+ e.preventDefault();
352
+ }, false);
353
+
354
+ // Button event listeners
355
+ startButton.addEventListener('click', startGame);
356
+ restartButton.addEventListener('click', startGame);
357
+
358
+ // Initial draw
359
+ drawGrid();
360
+ drawFood();
361
+ drawSnake();
362
+ });
363
+ </script>
364
+ <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=pijou/snake" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
365
+ </html>