LudoSLN commited on
Commit
f4beac0
·
verified ·
1 Parent(s): b6319b2

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +649 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Ludo Salenne
3
- emoji: 🐨
4
- colorFrom: yellow
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: ludo-salenne
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: yellow
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,649 @@
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="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>200K Brick Breaker - YouTube Celebration</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=Poppins:wght@400;600;700&display=swap');
11
+
12
+ body {
13
+ font-family: 'Poppins', sans-serif;
14
+ background: linear-gradient(135deg, #1a1a2e, #16213e);
15
+ overflow: hidden;
16
+ }
17
+
18
+ #gameCanvas {
19
+ box-shadow: 0 0 30px rgba(0, 150, 255, 0.5);
20
+ border-radius: 10px;
21
+ }
22
+
23
+ .brick {
24
+ transition: all 0.2s ease;
25
+ }
26
+
27
+ .brick-hit {
28
+ animation: hit 0.3s ease;
29
+ }
30
+
31
+ @keyframes hit {
32
+ 0% { transform: scale(1); }
33
+ 50% { transform: scale(1.1); }
34
+ 100% { transform: scale(1); }
35
+ }
36
+
37
+ .confetti {
38
+ position: absolute;
39
+ width: 10px;
40
+ height: 10px;
41
+ background-color: #f00;
42
+ border-radius: 50%;
43
+ pointer-events: none;
44
+ }
45
+ </style>
46
+ </head>
47
+ <body class="min-h-screen flex flex-col items-center justify-center text-white">
48
+ <div class="text-center mb-6">
49
+ <h1 class="text-4xl font-bold mb-2 bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-600">
50
+ Brick Breaker 200K
51
+ </h1>
52
+ <p class="text-lg text-blue-200">Cassez les briques pour célébrer nos 200 000 abonnés !</p>
53
+ </div>
54
+
55
+ <div class="relative">
56
+ <canvas id="gameCanvas" width="800" height="500" class="bg-gray-900 border-2 border-blue-500"></canvas>
57
+
58
+ <div id="startScreen" class="absolute inset-0 flex flex-col items-center justify-center bg-black bg-opacity-70">
59
+ <div class="text-center p-8 rounded-xl bg-gray-800 border border-blue-500 max-w-md">
60
+ <i class="fas fa-gamepad text-5xl text-blue-400 mb-4"></i>
61
+ <h2 class="text-2xl font-bold mb-4">Brick Breaker 200K</h2>
62
+ <p class="mb-6">Utilisez les flèches ou la souris pour déplacer la raquette et cassez toutes les briques !</p>
63
+ <button id="startButton" class="px-6 py-3 bg-gradient-to-r from-blue-500 to-purple-600 rounded-full font-bold hover:from-blue-600 hover:to-purple-700 transition-all transform hover:scale-105 shadow-lg">
64
+ COMMENCER LE JEU
65
+ </button>
66
+ </div>
67
+ </div>
68
+
69
+ <div id="gameOverScreen" class="absolute inset-0 hidden flex-col items-center justify-center bg-black bg-opacity-70">
70
+ <div class="text-center p-8 rounded-xl bg-gray-800 border border-blue-500 max-w-md">
71
+ <i class="fas fa-trophy text-5xl text-yellow-400 mb-4"></i>
72
+ <h2 id="resultTitle" class="text-2xl font-bold mb-2">Félicitations !</h2>
73
+ <p id="resultMessage" class="mb-4">Vous avez cassé toutes les briques des 200K abonnés !</p>
74
+ <div class="flex justify-center space-x-4">
75
+ <button id="restartButton" class="px-4 py-2 bg-blue-500 rounded-full font-bold hover:bg-blue-600 transition">
76
+ Rejouer
77
+ </button>
78
+ <button id="shareButton" class="px-4 py-2 bg-purple-500 rounded-full font-bold hover:bg-purple-600 transition">
79
+ <i class="fas fa-share mr-2"></i>Partager
80
+ </button>
81
+ </div>
82
+ </div>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="mt-6 flex items-center space-x-8">
87
+ <div class="flex items-center space-x-2">
88
+ <i class="fas fa-heart text-red-500"></i>
89
+ <span id="lives">3</span>
90
+ </div>
91
+ <div class="flex items-center space-x-2">
92
+ <i class="fas fa-bolt text-yellow-400"></i>
93
+ <span id="score">0</span>
94
+ </div>
95
+ <div class="flex items-center space-x-2">
96
+ <i class="fas fa-layer-group text-blue-400"></i>
97
+ <span id="level">1</span>
98
+ </div>
99
+ </div>
100
+
101
+ <div class="mt-8 text-center text-blue-300">
102
+ <p>Merci à nos 200 000 abonnés ! Abonnez-vous pour plus de jeux amusants.</p>
103
+ <div class="mt-2 flex justify-center space-x-4">
104
+ <button class="px-4 py-2 bg-red-600 rounded-full font-bold hover:bg-red-700 transition flex items-center">
105
+ <i class="fab fa-youtube mr-2"></i> YouTube
106
+ </button>
107
+ </div>
108
+ </div>
109
+
110
+ <script>
111
+ document.addEventListener('DOMContentLoaded', () => {
112
+ // Canvas setup
113
+ const canvas = document.getElementById('gameCanvas');
114
+ const ctx = canvas.getContext('2d');
115
+
116
+ // Game elements
117
+ const paddle = {
118
+ width: 100,
119
+ height: 15,
120
+ x: canvas.width / 2 - 50,
121
+ speed: 8,
122
+ isMoving: false,
123
+ direction: 0
124
+ };
125
+
126
+ const ball = {
127
+ x: canvas.width / 2,
128
+ y: canvas.height - 30,
129
+ radius: 8,
130
+ dx: 4,
131
+ dy: -4,
132
+ speed: 4
133
+ };
134
+
135
+ // Game state
136
+ let lives = 3;
137
+ let score = 0;
138
+ let level = 1;
139
+ let gameRunning = false;
140
+ let bricks = [];
141
+ let brickRowCount = 5;
142
+ let brickColumnCount = 10;
143
+ let brickWidth = 75;
144
+ let brickHeight = 20;
145
+ let brickPadding = 10;
146
+ let brickOffsetTop = 60;
147
+ let brickOffsetLeft = 30;
148
+
149
+ // DOM elements
150
+ const livesDisplay = document.getElementById('lives');
151
+ const scoreDisplay = document.getElementById('score');
152
+ const levelDisplay = document.getElementById('level');
153
+ const startScreen = document.getElementById('startScreen');
154
+ const gameOverScreen = document.getElementById('gameOverScreen');
155
+ const startButton = document.getElementById('startButton');
156
+ const restartButton = document.getElementById('restartButton');
157
+ const shareButton = document.getElementById('shareButton');
158
+ const resultTitle = document.getElementById('resultTitle');
159
+ const resultMessage = document.getElementById('resultMessage');
160
+
161
+ // Initialize bricks
162
+ function initBricks() {
163
+ bricks = [];
164
+ const colors = ['#FF5252', '#FFD740', '#69F0AE', '#40C4FF', '#E040FB'];
165
+
166
+ for (let c = 0; c < brickColumnCount; c++) {
167
+ bricks[c] = [];
168
+ for (let r = 0; r < brickRowCount; r++) {
169
+ const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
170
+ const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
171
+ const colorIndex = Math.floor(Math.random() * colors.length);
172
+
173
+ bricks[c][r] = {
174
+ x: brickX,
175
+ y: brickY,
176
+ status: 1,
177
+ color: colors[colorIndex],
178
+ hit: false
179
+ };
180
+ }
181
+ }
182
+ }
183
+
184
+ // Draw paddle
185
+ function drawPaddle() {
186
+ ctx.beginPath();
187
+ ctx.rect(paddle.x, canvas.height - paddle.height, paddle.width, paddle.height);
188
+ ctx.fillStyle = '#3D5AFE';
189
+ ctx.fill();
190
+ ctx.closePath();
191
+
192
+ // Add gradient effect
193
+ const gradient = ctx.createLinearGradient(paddle.x, 0, paddle.x + paddle.width, 0);
194
+ gradient.addColorStop(0, '#3D5AFE');
195
+ gradient.addColorStop(1, '#2962FF');
196
+ ctx.fillStyle = gradient;
197
+ ctx.fill();
198
+
199
+ // Add shine effect
200
+ ctx.beginPath();
201
+ ctx.moveTo(paddle.x + 5, canvas.height - paddle.height);
202
+ ctx.lineTo(paddle.x + paddle.width - 5, canvas.height - paddle.height);
203
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
204
+ ctx.lineWidth = 2;
205
+ ctx.stroke();
206
+ }
207
+
208
+ // Draw ball
209
+ function drawBall() {
210
+ ctx.beginPath();
211
+ ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
212
+
213
+ // Add gradient to ball
214
+ const gradient = ctx.createRadialGradient(
215
+ ball.x - ball.radius / 3,
216
+ ball.y - ball.radius / 3,
217
+ ball.radius / 3,
218
+ ball.x,
219
+ ball.y,
220
+ ball.radius
221
+ );
222
+ gradient.addColorStop(0, '#FFFFFF');
223
+ gradient.addColorStop(1, '#00B0FF');
224
+ ctx.fillStyle = gradient;
225
+ ctx.fill();
226
+ ctx.closePath();
227
+
228
+ // Add shine to ball
229
+ ctx.beginPath();
230
+ ctx.arc(ball.x - ball.radius / 3, ball.y - ball.radius / 3, ball.radius / 4, 0, Math.PI * 2);
231
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
232
+ ctx.fill();
233
+ }
234
+
235
+ // Draw bricks
236
+ function drawBricks() {
237
+ for (let c = 0; c < brickColumnCount; c++) {
238
+ for (let r = 0; r < brickRowCount; r++) {
239
+ if (bricks[c][r].status === 1) {
240
+ const brick = bricks[c][r];
241
+
242
+ // Draw brick with shadow
243
+ ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
244
+ ctx.shadowBlur = 5;
245
+ ctx.shadowOffsetX = 2;
246
+ ctx.shadowOffsetY = 2;
247
+
248
+ ctx.beginPath();
249
+ ctx.rect(brick.x, brick.y, brickWidth, brickHeight);
250
+ ctx.fillStyle = brick.color;
251
+ ctx.fill();
252
+
253
+ // Reset shadow
254
+ ctx.shadowColor = 'transparent';
255
+
256
+ // Add highlight to brick
257
+ ctx.beginPath();
258
+ ctx.moveTo(brick.x, brick.y);
259
+ ctx.lineTo(brick.x + brickWidth, brick.y);
260
+ ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
261
+ ctx.lineWidth = 2;
262
+ ctx.stroke();
263
+
264
+ // Add "200K" text to some bricks
265
+ if (Math.random() > 0.7) {
266
+ ctx.font = 'bold 10px Arial';
267
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
268
+ ctx.fillText('200K', brick.x + brickWidth/2 - 15, brick.y + brickHeight/2 + 3);
269
+ }
270
+
271
+ // Animation when hit
272
+ if (brick.hit) {
273
+ ctx.beginPath();
274
+ ctx.rect(brick.x + 2, brick.y + 2, brickWidth - 4, brickHeight - 4);
275
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
276
+ ctx.fill();
277
+ brick.hit = false;
278
+ }
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ // Collision detection
285
+ function collisionDetection() {
286
+ for (let c = 0; c < brickColumnCount; c++) {
287
+ for (let r = 0; r < brickRowCount; r++) {
288
+ const brick = bricks[c][r];
289
+ if (brick.status === 1) {
290
+ if (
291
+ ball.x + ball.radius > brick.x &&
292
+ ball.x - ball.radius < brick.x + brickWidth &&
293
+ ball.y + ball.radius > brick.y &&
294
+ ball.y - ball.radius < brick.y + brickHeight
295
+ ) {
296
+ brick.hit = true;
297
+ ball.dy = -ball.dy;
298
+ brick.status = 0;
299
+ score += 10;
300
+ scoreDisplay.textContent = score;
301
+ createParticles(brick.x + brickWidth/2, brick.y + brickHeight/2, brick.color);
302
+
303
+ // Check if all bricks are cleared
304
+ if (checkLevelComplete()) {
305
+ levelComplete();
306
+ }
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ // Check if level is complete
314
+ function checkLevelComplete() {
315
+ for (let c = 0; c < brickColumnCount; c++) {
316
+ for (let r = 0; r < brickRowCount; r++) {
317
+ if (bricks[c][r].status === 1) {
318
+ return false;
319
+ }
320
+ }
321
+ }
322
+ return true;
323
+ }
324
+
325
+ // Level complete
326
+ function levelComplete() {
327
+ level++;
328
+ levelDisplay.textContent = level;
329
+
330
+ // Increase difficulty
331
+ ball.speed += 0.5;
332
+ ball.dx = ball.dx > 0 ? ball.speed : -ball.speed;
333
+ ball.dy = -ball.speed;
334
+
335
+ // Reset ball and paddle
336
+ ball.x = canvas.width / 2;
337
+ ball.y = canvas.height - 30;
338
+ paddle.x = canvas.width / 2 - paddle.width / 2;
339
+
340
+ // Create new bricks
341
+ setTimeout(() => {
342
+ initBricks();
343
+ }, 1000);
344
+ }
345
+
346
+ // Create particles when brick is hit
347
+ function createParticles(x, y, color) {
348
+ const particleCount = 8;
349
+ for (let i = 0; i < particleCount; i++) {
350
+ const particle = document.createElement('div');
351
+ particle.className = 'confetti absolute';
352
+ particle.style.left = `${x}px`;
353
+ particle.style.top = `${y}px`;
354
+ particle.style.backgroundColor = color;
355
+ particle.style.width = `${Math.random() * 8 + 4}px`;
356
+ particle.style.height = particle.style.width;
357
+ particle.style.borderRadius = '50%';
358
+
359
+ document.body.appendChild(particle);
360
+
361
+ const angle = Math.random() * Math.PI * 2;
362
+ const velocity = Math.random() * 5 + 2;
363
+ const xVelocity = Math.cos(angle) * velocity;
364
+ const yVelocity = Math.sin(angle) * velocity;
365
+
366
+ let opacity = 1;
367
+ const fadeInterval = setInterval(() => {
368
+ opacity -= 0.05;
369
+ particle.style.opacity = opacity;
370
+
371
+ if (opacity <= 0) {
372
+ clearInterval(fadeInterval);
373
+ particle.remove();
374
+ }
375
+ }, 30);
376
+
377
+ let posX = x;
378
+ let posY = y;
379
+ const moveInterval = setInterval(() => {
380
+ posX += xVelocity;
381
+ posY += yVelocity;
382
+ yVelocity += 0.1; // gravity
383
+
384
+ particle.style.left = `${posX}px`;
385
+ particle.style.top = `${posY}px`;
386
+
387
+ if (opacity <= 0) {
388
+ clearInterval(moveInterval);
389
+ }
390
+ }, 30);
391
+ }
392
+ }
393
+
394
+ // Create celebration confetti
395
+ function createConfetti() {
396
+ const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];
397
+ const count = 150;
398
+
399
+ for (let i = 0; i < count; i++) {
400
+ const confetti = document.createElement('div');
401
+ confetti.className = 'confetti absolute';
402
+ confetti.style.left = `${Math.random() * window.innerWidth}px`;
403
+ confetti.style.top = `${-10}px`;
404
+ confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
405
+ confetti.style.width = `${Math.random() * 10 + 5}px`;
406
+ confetti.style.height = `${Math.random() * 10 + 5}px`;
407
+ confetti.style.borderRadius = Math.random() > 0.5 ? '50%' : '0';
408
+ confetti.style.transform = `rotate(${Math.random() * 360}deg)`;
409
+
410
+ document.body.appendChild(confetti);
411
+
412
+ const animationDuration = Math.random() * 3 + 2;
413
+ confetti.style.animation = `fall ${animationDuration}s linear forwards`;
414
+
415
+ // Add animation
416
+ const keyframes = `
417
+ @keyframes fall {
418
+ to {
419
+ transform: translateY(${window.innerHeight + 10}px) rotate(${Math.random() * 360}deg);
420
+ opacity: 0;
421
+ }
422
+ }
423
+ `;
424
+
425
+ const styleEl = document.createElement('style');
426
+ styleEl.innerHTML = keyframes;
427
+ document.head.appendChild(styleEl);
428
+
429
+ // Remove after animation
430
+ setTimeout(() => {
431
+ confetti.remove();
432
+ styleEl.remove();
433
+ }, animationDuration * 1000);
434
+ }
435
+ }
436
+
437
+ // Ball movement
438
+ function moveBall() {
439
+ // Wall collision (left/right)
440
+ if (ball.x + ball.dx > canvas.width - ball.radius || ball.x + ball.dx < ball.radius) {
441
+ ball.dx = -ball.dx;
442
+ }
443
+
444
+ // Wall collision (top)
445
+ if (ball.y + ball.dy < ball.radius) {
446
+ ball.dy = -ball.dy;
447
+ }
448
+
449
+ // Paddle collision
450
+ if (
451
+ ball.y + ball.dy > canvas.height - ball.radius - paddle.height &&
452
+ ball.x > paddle.x &&
453
+ ball.x < paddle.x + paddle.width
454
+ ) {
455
+ // Calculate bounce angle based on where ball hits paddle
456
+ const hitPosition = (ball.x - (paddle.x + paddle.width / 2)) / (paddle.width / 2);
457
+ ball.dx = hitPosition * 5;
458
+ ball.dy = -Math.abs(ball.dy);
459
+
460
+ // Add effect to paddle
461
+ const gradient = ctx.createLinearGradient(paddle.x, 0, paddle.x + paddle.width, 0);
462
+ gradient.addColorStop(0, '#FF4081');
463
+ gradient.addColorStop(1, '#7C4DFF');
464
+ ctx.fillStyle = gradient;
465
+ }
466
+
467
+ // Bottom wall (lose life)
468
+ if (ball.y + ball.dy > canvas.height - ball.radius) {
469
+ if (lives > 0) {
470
+ lives--;
471
+ livesDisplay.textContent = lives;
472
+
473
+ // Reset ball and paddle
474
+ ball.x = canvas.width / 2;
475
+ ball.y = canvas.height - 30;
476
+ ball.dx = 4;
477
+ ball.dy = -4;
478
+ paddle.x = canvas.width / 2 - paddle.width / 2;
479
+
480
+ // Flash screen red
481
+ document.body.style.backgroundColor = '#ff0000';
482
+ setTimeout(() => {
483
+ document.body.style.backgroundColor = '';
484
+ }, 100);
485
+ } else {
486
+ gameOver(false);
487
+ }
488
+ }
489
+
490
+ ball.x += ball.dx;
491
+ ball.y += ball.dy;
492
+ }
493
+
494
+ // Paddle movement
495
+ function movePaddle() {
496
+ if (paddle.isMoving) {
497
+ paddle.x += paddle.direction * paddle.speed;
498
+
499
+ // Keep paddle within canvas
500
+ if (paddle.x < 0) {
501
+ paddle.x = 0;
502
+ } else if (paddle.x + paddle.width > canvas.width) {
503
+ paddle.x = canvas.width - paddle.width;
504
+ }
505
+ }
506
+ }
507
+
508
+ // Draw game
509
+ function draw() {
510
+ // Clear canvas
511
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
512
+
513
+ // Draw elements
514
+ drawBricks();
515
+ drawPaddle();
516
+ drawBall();
517
+
518
+ // Collision detection
519
+ collisionDetection();
520
+
521
+ // Move elements
522
+ moveBall();
523
+ movePaddle();
524
+
525
+ // Continue animation if game is running
526
+ if (gameRunning) {
527
+ requestAnimationFrame(draw);
528
+ }
529
+ }
530
+
531
+ // Start game
532
+ function startGame() {
533
+ lives = 3;
534
+ score = 0;
535
+ level = 1;
536
+
537
+ livesDisplay.textContent = lives;
538
+ scoreDisplay.textContent = score;
539
+ levelDisplay.textContent = level;
540
+
541
+ initBricks();
542
+ gameRunning = true;
543
+ startScreen.classList.add('hidden');
544
+ gameOverScreen.classList.add('hidden');
545
+
546
+ // Reset ball and paddle
547
+ ball.x = canvas.width / 2;
548
+ ball.y = canvas.height - 30;
549
+ ball.dx = 4;
550
+ ball.dy = -4;
551
+ ball.speed = 4;
552
+ paddle.x = canvas.width / 2 - paddle.width / 2;
553
+
554
+ draw();
555
+ }
556
+
557
+ // Game over
558
+ function gameOver(win) {
559
+ gameRunning = false;
560
+
561
+ if (win) {
562
+ resultTitle.textContent = "Félicitations !";
563
+ resultMessage.textContent = "Vous avez cassé toutes les briques des 200K abonnés !";
564
+ createConfetti();
565
+ } else {
566
+ resultTitle.textContent = "Game Over";
567
+ resultMessage.textContent = "Vous avez perdu toutes vos vies. Essayez encore !";
568
+ }
569
+
570
+ gameOverScreen.classList.remove('hidden');
571
+ }
572
+
573
+ // Event listeners
574
+ startButton.addEventListener('click', startGame);
575
+ restartButton.addEventListener('click', startGame);
576
+
577
+ shareButton.addEventListener('click', () => {
578
+ if (navigator.share) {
579
+ navigator.share({
580
+ title: '200K Brick Breaker',
581
+ text: `J'ai marqué ${score} points dans le jeu Brick Breaker 200K !`,
582
+ url: window.location.href
583
+ }).catch(console.error);
584
+ } else {
585
+ alert(`Partagez votre score de ${score} points sur les réseaux sociaux !`);
586
+ }
587
+ });
588
+
589
+ // Keyboard controls
590
+ document.addEventListener('keydown', (e) => {
591
+ if (e.key === 'Right' || e.key === 'ArrowRight') {
592
+ paddle.isMoving = true;
593
+ paddle.direction = 1;
594
+ } else if (e.key === 'Left' || e.key === 'ArrowLeft') {
595
+ paddle.isMoving = true;
596
+ paddle.direction = -1;
597
+ } else if (e.key === ' ' && !gameRunning && !startScreen.classList.contains('hidden')) {
598
+ startGame();
599
+ }
600
+ });
601
+
602
+ document.addEventListener('keyup', (e) => {
603
+ if (e.key === 'Right' || e.key === 'ArrowRight' || e.key === 'Left' || e.key === 'ArrowLeft') {
604
+ paddle.isMoving = false;
605
+ }
606
+ });
607
+
608
+ // Mouse/touch controls
609
+ canvas.addEventListener('mousemove', (e) => {
610
+ if (!gameRunning) return;
611
+
612
+ const relativeX = e.clientX - canvas.getBoundingClientRect().left;
613
+ if (relativeX > 0 && relativeX < canvas.width) {
614
+ paddle.x = relativeX - paddle.width / 2;
615
+
616
+ // Keep paddle within canvas
617
+ if (paddle.x < 0) {
618
+ paddle.x = 0;
619
+ } else if (paddle.x + paddle.width > canvas.width) {
620
+ paddle.x = canvas.width - paddle.width;
621
+ }
622
+ }
623
+ });
624
+
625
+ // Touch controls for mobile
626
+ canvas.addEventListener('touchmove', (e) => {
627
+ if (!gameRunning) return;
628
+ e.preventDefault();
629
+
630
+ const touch = e.touches[0];
631
+ const relativeX = touch.clientX - canvas.getBoundingClientRect().left;
632
+ if (relativeX > 0 && relativeX < canvas.width) {
633
+ paddle.x = relativeX - paddle.width / 2;
634
+
635
+ // Keep paddle within canvas
636
+ if (paddle.x < 0) {
637
+ paddle.x = 0;
638
+ } else if (paddle.x + paddle.width > canvas.width) {
639
+ paddle.x = canvas.width - paddle.width;
640
+ }
641
+ }
642
+ });
643
+
644
+ // Initialize game
645
+ initBricks();
646
+ });
647
+ </script>
648
+ <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=LudoSLN/ludo-salenne" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
649
+ </html>