smjain commited on
Commit
de875ad
Β·
verified Β·
1 Parent(s): 50b95df

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +665 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Game
3
- emoji: 🐒
4
- colorFrom: pink
5
- colorTo: gray
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: game
3
+ emoji: 🐳
4
+ colorFrom: blue
5
+ colorTo: blue
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,665 @@
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>Modi vs Kejriwal Cricket Battle</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Arial', sans-serif;
16
+ background: linear-gradient(to right, #ff9933, #ffffff, #138808);
17
+ height: 100vh;
18
+ overflow: hidden;
19
+ display: flex;
20
+ justify-content: center;
21
+ align-items: center;
22
+ position: relative;
23
+ }
24
+
25
+ #gameCanvas {
26
+ background-color: #1e8449;
27
+ border: 10px solid #800080;
28
+ border-radius: 15px;
29
+ box-shadow: 0 0 40px rgba(0, 0, 0, 0.6);
30
+ }
31
+
32
+ #scoreboard {
33
+ position: absolute;
34
+ top: 20px;
35
+ left: 50%;
36
+ transform: translateX(-50%);
37
+ color: white;
38
+ font-size: 28px;
39
+ text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.8);
40
+ padding: 15px 30px;
41
+ background: rgba(0, 0, 0, 0.7);
42
+ border-radius: 15px;
43
+ border: 3px solid gold;
44
+ font-weight: bold;
45
+ }
46
+
47
+ #gameOver {
48
+ position: absolute;
49
+ top: 50%;
50
+ left: 50%;
51
+ transform: translate(-50%, -50%);
52
+ color: white;
53
+ font-size: 60px;
54
+ text-align: center;
55
+ display: none;
56
+ text-shadow: 5px 5px 10px rgba(0, 0, 0, 0.9);
57
+ background: rgba(139, 0, 0, 0.9);
58
+ padding: 40px;
59
+ border-radius: 25px;
60
+ border: 5px solid #ffd700;
61
+ z-index: 100;
62
+ }
63
+
64
+ #restartBtn {
65
+ margin-top: 30px;
66
+ padding: 15px 30px;
67
+ font-size: 28px;
68
+ background: linear-gradient(to right, #ff9933, #ffffff, #138808);
69
+ border: 3px solid #000080;
70
+ border-radius: 15px;
71
+ cursor: pointer;
72
+ box-shadow: 0 0 20px rgba(255, 255, 255, 0.7);
73
+ transition: all 0.3s;
74
+ font-weight: bold;
75
+ }
76
+
77
+ #restartBtn:hover {
78
+ transform: scale(1.1);
79
+ box-shadow: 0 0 30px rgba(255, 255, 255, 0.9);
80
+ }
81
+
82
+ #controls {
83
+ position: absolute;
84
+ bottom: 30px;
85
+ left: 50%;
86
+ transform: translateX(-50%);
87
+ color: white;
88
+ font-size: 22px;
89
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
90
+ text-align: center;
91
+ background: rgba(0, 0, 0, 0.7);
92
+ padding: 15px;
93
+ border-radius: 15px;
94
+ border: 3px solid #ff0000;
95
+ }
96
+
97
+ #title {
98
+ position: absolute;
99
+ top: -70px;
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ color: #000080;
103
+ font-size: 40px;
104
+ text-shadow: 3px 3px 6px rgba(255, 255, 255, 0.7);
105
+ font-weight: bold;
106
+ white-space: nowrap;
107
+ }
108
+
109
+ /* Cheering crowd element */
110
+ .crowd {
111
+ position: absolute;
112
+ bottom: 0;
113
+ width: 100%;
114
+ height: 20%;
115
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 20"><circle cx="10" cy="10" r="5" fill="%23fff"/><circle cx="30" cy="8" r="4" fill="%23ff9933"/><circle cx="50" cy="12" r="5" fill="%23fff"/><circle cx="70" cy="9" r="4" fill="%23138808"/><circle cx="90" cy="11" r="5" fill="%23fff"/></svg>');
116
+ background-repeat: repeat-x;
117
+ opacity: 0.6;
118
+ z-index: -1;
119
+ }
120
+
121
+ .speech-bubble {
122
+ position: absolute;
123
+ background: white;
124
+ border-radius: 20px;
125
+ padding: 10px 15px;
126
+ font-size: 14px;
127
+ color: black;
128
+ text-align: center;
129
+ box-shadow: 2px 2px 4px rgba(0,0,0,0.2);
130
+ display: none;
131
+ white-space: nowrap;
132
+ z-index: 10;
133
+ }
134
+
135
+ .bubble-bat {
136
+ bottom: 100px;
137
+ left: 50%;
138
+ transform: translateX(-50%);
139
+ }
140
+
141
+ .bubble-ball {
142
+ top: 150px;
143
+ left: 50%;
144
+ transform: translateX(-50%);
145
+ }
146
+ </style>
147
+ </head>
148
+ <body>
149
+ <div id="title">Modi Cricket Bat vs Kejriwal Ball</div>
150
+ <div class="crowd"></div>
151
+ <canvas id="gameCanvas"></canvas>
152
+ <div id="scoreboard">🏏 Score: 0 | 🎳 Balls: 0 | ⚑ Speed: 1x</div>
153
+ <div id="gameOver">
154
+ <h1>Game Over!</h1>
155
+ <p id="finalScore" style="font-size: 36px; margin: 20px 0;">Your score: 0</p>
156
+ <button id="restartBtn">🚩 Play Again</button>
157
+ </div>
158
+ <div id="controls">πŸ•ΉοΈ Use <strong>LEFT ←</strong> and <strong>RIGHT β†’</strong> arrow keys to move</div>
159
+
160
+ <!-- Speech bubbles -->
161
+ <div class="speech-bubble bubble-bat" id="modiSpeech">Mitron!</div>
162
+ <div class="speech-bubble bubble-ball" id="kejriwalSpeech">Kya bekaar bowling hai!</div>
163
+
164
+ <script>
165
+ const canvas = document.getElementById('gameCanvas');
166
+ const ctx = canvas.getContext('2d');
167
+ const scoreboard = document.getElementById('scoreboard');
168
+ const gameOverScreen = document.getElementById('gameOver');
169
+ const finalScore = document.getElementById('finalScore');
170
+ const restartBtn = document.getElementById('restartBtn');
171
+ const modiSpeech = document.getElementById('modiSpeech');
172
+ const kejriwalSpeech = document.getElementById('kejriwalSpeech');
173
+
174
+ // Set canvas size
175
+ canvas.width = 800;
176
+ canvas.height = 600;
177
+
178
+ // Game variables
179
+ let score = 0;
180
+ let ballsFaced = 0;
181
+ let gameActive = false;
182
+ let gameSpeed = 1;
183
+ let lastDirection = 'right';
184
+
185
+ // Bat (Modi)
186
+ const bat = {
187
+ x: canvas.width / 2 - 75,
188
+ y: canvas.height - 40,
189
+ width: 150,
190
+ height: 30,
191
+ speed: 15
192
+ };
193
+
194
+ // Ball (Kejriwal)
195
+ const ball = {
196
+ x: 0,
197
+ y: 0,
198
+ radius: 20,
199
+ speedX: 0,
200
+ speedY: 0,
201
+ active: false
202
+ };
203
+
204
+ // Targets (Kejriwal scams as bricks)
205
+ const scams = [
206
+ "Liquor Scam", "CS Bus Scam", "Water Tanker Scam",
207
+ "PWD Scam", "Excise Scam", "Classroom Scam",
208
+ "Hospitals Scam", "Mohalla Clinics", "DJB Scam",
209
+ "Wifi Scam", "Waste Mgmt Scam", "Electricity Scam"
210
+ ];
211
+
212
+ const brickRowCount = 3;
213
+ const brickColumnCount = 4;
214
+ const brickWidth = 170;
215
+ const brickHeight = 35;
216
+ const brickPadding = 15;
217
+ const brickOffsetTop = 80;
218
+ const brickOffsetLeft = 60;
219
+
220
+ const bricks = [];
221
+ for (let c = 0; c < brickColumnCount; c++) {
222
+ bricks[c] = [];
223
+ for (let r = 0; r < brickRowCount; r++) {
224
+ const scamIndex = (c * brickRowCount + r) % scams.length;
225
+ bricks[c][r] = {
226
+ x: 0,
227
+ y: 0,
228
+ status: 1,
229
+ scam: scams[scamIndex]
230
+ };
231
+ }
232
+ }
233
+
234
+ // Modi animation states (emotes)
235
+ const modiFrames = [
236
+ "πŸ™‚", "😊", "🀩", "😎", "😑", "🀬", "😁", "πŸ€‘"
237
+ ];
238
+ let currentModiFrame = 0;
239
+ let frameCounter = 0;
240
+
241
+ // Kejriwal animation states (reactions)
242
+ const kejriwalFrames = [
243
+ "😐", "πŸ˜•", "😲", "😨", "😡", "😀", "😷", "πŸ₯΅"
244
+ ];
245
+ let currentKejriwalFrame = 0;
246
+
247
+ // Sound effects
248
+ const sounds = {
249
+ hit: ["Mann ki baat", "Mitron!", "Achhe din!", "Sabka saath sabka vikas!"],
250
+ miss: ["Main bhagwan ka diya hua PM hun!", "Inhe kuchh nahi aata!", "Besharmi ki hadd hai!"]
251
+ };
252
+
253
+ // Initialize the game
254
+ function init() {
255
+ score = 0;
256
+ ballsFaced = 0;
257
+ gameActive = true;
258
+ gameSpeed = 1;
259
+
260
+ // Reset bat position
261
+ bat.x = canvas.width / 2 - bat.width / 2;
262
+
263
+ // Reset bricks
264
+ for (let c = 0; c < brickColumnCount; c++) {
265
+ for (let r = 0; r < brickRowCount; r++) {
266
+ bricks[c][r].status = 1;
267
+ }
268
+ }
269
+
270
+ // Start with a new ball
271
+ resetBall();
272
+
273
+ // Hide game over screen and speech bubbles
274
+ gameOverScreen.style.display = 'none';
275
+ modiSpeech.style.display = 'none';
276
+ kejriwalSpeech.style.display = 'none';
277
+
278
+ // Start the game loop
279
+ requestAnimationFrame(gameLoop);
280
+ }
281
+
282
+ // Reset ball position
283
+ function resetBall() {
284
+ ball.x = canvas.width / 2;
285
+ ball.y = 50;
286
+ ball.speedX = (Math.random() * 6 - 3) * gameSpeed;
287
+ ball.speedY = 3 * gameSpeed;
288
+ ball.active = true;
289
+ ballsFaced++;
290
+ currentKejriwalFrame = Math.floor(Math.random() * kejriwalFrames.length);
291
+ updateScoreboard();
292
+ }
293
+
294
+ // Show speech bubble
295
+ function showSpeech(bubble, text) {
296
+ bubble.textContent = text;
297
+ bubble.style.display = 'block';
298
+ setTimeout(() => {
299
+ bubble.style.display = 'none';
300
+ }, 1000);
301
+ }
302
+
303
+ // Draw the bat (Modi)
304
+ function drawBat() {
305
+ // Bat body with tricolor
306
+ ctx.fillStyle = '#FF9933'; // Saffron
307
+ ctx.fillRect(bat.x, bat.y, bat.width/3, bat.height);
308
+ ctx.fillStyle = '#FFFFFF'; // White
309
+ ctx.fillRect(bat.x + bat.width/3, bat.y, bat.width/3, bat.height);
310
+ ctx.fillStyle = '#138808'; // Green
311
+ ctx.fillRect(bat.x + 2*bat.width/3, bat.y, bat.width/3, bat.height);
312
+
313
+ // Border
314
+ ctx.strokeStyle = '#000080';
315
+ ctx.lineWidth = 3;
316
+ ctx.strokeRect(bat.x, bat.y, bat.width, bat.height);
317
+
318
+ // Modi face on bat
319
+ const faceRadius = 25;
320
+ const faceX = lastDirection === 'right' ? bat.x + bat.width - 10 : bat.x + 10;
321
+
322
+ // Modi face circle
323
+ ctx.fillStyle = '#ffcc00';
324
+ ctx.beginPath();
325
+ ctx.arc(faceX, bat.y - faceRadius/2, faceRadius, 0, Math.PI * 2);
326
+ ctx.fill();
327
+ ctx.strokeStyle = '#000';
328
+ ctx.lineWidth = 2;
329
+ ctx.stroke();
330
+
331
+ // Modi eyes
332
+ ctx.fillStyle = '#000';
333
+ ctx.beginPath();
334
+ ctx.arc(faceX - 10, bat.y - faceRadius/2 - 5, 3, 0, Math.PI * 2);
335
+ ctx.fill();
336
+ ctx.beginPath();
337
+ ctx.arc(faceX + 10, bat.y - faceRadius/2 - 5, 3, 0, Math.PI * 2);
338
+ ctx.fill();
339
+
340
+ // Modi mouth (with current frame)
341
+ ctx.font = '20px Arial';
342
+ ctx.fillText(modiFrames[currentModiFrame], faceX - 10, bat.y - faceRadius/2 + 15);
343
+
344
+ // Animate Modi every 10 frames
345
+ frameCounter++;
346
+ if (frameCounter % 10 === 0) {
347
+ currentModiFrame = (currentModiFrame + 1) % modiFrames.length;
348
+ }
349
+
350
+ // Modi's name tag
351
+ ctx.font = 'bold 16px Arial';
352
+ ctx.fillStyle = '#000080';
353
+ ctx.fillText("Narendra Modi", bat.x + bat.width/2 - 50, bat.y - 5);
354
+ }
355
+
356
+ // Draw the ball (Kejriwal)
357
+ function drawBall() {
358
+ // Ball body
359
+ ctx.fillStyle = '#009688';
360
+ ctx.beginPath();
361
+ ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
362
+ ctx.fill();
363
+ ctx.strokeStyle = '#000';
364
+ ctx.lineWidth = 2;
365
+ ctx.stroke();
366
+
367
+ // Kejriwal face
368
+ ctx.font = '20px Arial';
369
+ ctx.fillText(kejriwalFrames[currentKejriwalFrame], ball.x - 10, ball.y + 5);
370
+
371
+ // Kejriwal name tag
372
+ ctx.font = 'bold 14px Arial';
373
+ ctx.fillStyle = '#000';
374
+ ctx.fillText("Kejriwal", ball.x - 25, ball.y - 15);
375
+
376
+ // Change expression when ball hits something
377
+ if (ball.y + ball.radius > canvas.height - 100) {
378
+ currentKejriwalFrame = Math.floor(Math.random() * kejriwalFrames.length);
379
+ }
380
+ }
381
+
382
+ // Draw scam bricks
383
+ function drawBricks() {
384
+ for (let c = 0; c < brickColumnCount; c++) {
385
+ for (let r = 0; r < brickRowCount; r++) {
386
+ if (bricks[c][r].status === 1) {
387
+ const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft;
388
+ const brickY = r * (brickHeight + brickPadding) + brickOffsetTop;
389
+ bricks[c][r].x = brickX;
390
+ bricks[c][r].y = brickY;
391
+
392
+ // Colors for the scam bricks
393
+ let brickColor;
394
+ switch (r) {
395
+ case 0: brickColor = '#800000'; break; // Red for serious scams
396
+ case 1: brickColor = '#4169E1'; break; // Blue for financial scams
397
+ case 2: brickColor = '#8B4513'; break; // Brown for other scams
398
+ default: brickColor = '#000000';
399
+ }
400
+
401
+ ctx.fillStyle = brickColor;
402
+ ctx.fillRect(brickX, brickY, brickWidth, brickHeight);
403
+
404
+ // Brick shadow effect
405
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.3)';
406
+ ctx.fillRect(brickX + 5, brickY + 5, brickWidth, brickHeight);
407
+
408
+ ctx.strokeStyle = '#000';
409
+ ctx.lineWidth = 1;
410
+ ctx.strokeRect(brickX, brickY, brickWidth, brickHeight);
411
+
412
+ // Scam labels
413
+ ctx.font = 'bold 12px Arial';
414
+ ctx.fillStyle = '#fff';
415
+ const scam = bricks[c][r].scam;
416
+ const maxLength = 15;
417
+ if (scam.length > maxLength) {
418
+ // Split long scam names into two lines
419
+ const words = scam.split(' ');
420
+ let line1 = '', line2 = '';
421
+ for (const word of words) {
422
+ if ((line1 + word).length <= maxLength) {
423
+ line1 += word + ' ';
424
+ } else {
425
+ line2 += word + ' ';
426
+ }
427
+ }
428
+ ctx.fillText(line1.trim(), brickX + 5, brickY + 15);
429
+ ctx.fillText(line2.trim(), brickX + 5, brickY + 30);
430
+ } else {
431
+ ctx.fillText(scam, brickX + 5, brickY + 20);
432
+ }
433
+ }
434
+ }
435
+ }
436
+ }
437
+
438
+ // Update scoreboard
439
+ function updateScoreboard() {
440
+ scoreboard.textContent = `🏏 Score: ${score} | 🎳 Balls: ${ballsFaced} | ⚑ Speed: ${gameSpeed.toFixed(1)}x`;
441
+ }
442
+
443
+ // Check collisions
444
+ function collisionDetection() {
445
+ for (let c = 0; c < brickColumnCount; c++) {
446
+ for (let r = 0; r < brickRowCount; r++) {
447
+ const brick = bricks[c][r];
448
+ if (brick.status === 1) {
449
+ if (
450
+ ball.x + ball.radius > brick.x &&
451
+ ball.x - ball.radius < brick.x + brickWidth &&
452
+ ball.y + ball.radius > brick.y &&
453
+ ball.y - ball.radius < brick.y + brickHeight
454
+ ) {
455
+ ball.speedY = -ball.speedY;
456
+ brick.status = 0;
457
+ score += (brickRowCount - r + 1) * 50;
458
+
459
+ // Show Modi's speech
460
+ const randomHitPhrase = sounds.hit[Math.floor(Math.random() * sounds.hit.length)];
461
+ showSpeech(modiSpeech, randomHitPhrase);
462
+
463
+ // Position speech bubble
464
+ modiSpeech.style.left = `${bat.x + bat.width/2}px`;
465
+ modiSpeech.style.bottom = `${canvas.height - bat.y + 30}px`;
466
+
467
+ currentKejriwalFrame = Math.min(kejriwalFrames.length - 1, currentKejriwalFrame + 1);
468
+ updateScoreboard();
469
+
470
+ // Check if all bricks are cleared
471
+ let allBricksCleared = true;
472
+ for (let c = 0; c < brickColumnCount; c++) {
473
+ for (let r = 0; r < brickRowCount; r++) {
474
+ if (bricks[c][r].status === 1) {
475
+ allBricksCleared = false;
476
+ break;
477
+ }
478
+ }
479
+ if (!allBricksCleared) break;
480
+ }
481
+
482
+ if (allBricksCleared) {
483
+ gameSpeed += 0.5;
484
+ // Cheering crowd effect
485
+ currentModiFrame = 2; // 🀩
486
+ setTimeout(() => currentModiFrame = 0, 500);
487
+ resetBricks();
488
+ showSpeech(modiSpeech, "Mera Bharat Mahan!");
489
+ }
490
+ }
491
+ }
492
+ }
493
+ }
494
+ }
495
+
496
+ // Reset all bricks
497
+ function resetBricks() {
498
+ for (let c = 0; c < brickColumnCount; c++) {
499
+ for (let r = 0; r < brickRowCount; r++) {
500
+ bricks[c][r].status = 1;
501
+ }
502
+ }
503
+ }
504
+
505
+ // Game loop
506
+ function gameLoop() {
507
+ if (!gameActive) return;
508
+
509
+ // Clear canvas with transparent overlay for trail effect
510
+ ctx.fillStyle = 'rgba(30, 132, 73, 0.2)';
511
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
512
+
513
+ // Draw game elements
514
+ drawBricks();
515
+ drawBat();
516
+ drawBall();
517
+
518
+ // Ball movement
519
+ if (ball.active) {
520
+ ball.x += ball.speedX;
521
+ ball.y += ball.speedY;
522
+
523
+ // Wall collision
524
+ if (ball.x + ball.radius > canvas.width || ball.x - ball.radius < 0) {
525
+ ball.speedX = -ball.speedX;
526
+ currentKejriwalFrame = Math.floor(Math.random() * kejriwalFrames.length);
527
+ }
528
+
529
+ if (ball.y - ball.radius < 0) {
530
+ ball.speedY = -ball.speedY;
531
+ currentKejriwalFrame = Math.floor(Math.random() * kejriwalFrames.length);
532
+ }
533
+
534
+ // Bat collision
535
+ if (
536
+ ball.y + ball.radius > bat.y &&
537
+ ball.x > bat.x &&
538
+ ball.x < bat.x + bat.width
539
+ ) {
540
+ // Change Modi's expression to happy
541
+ currentModiFrame = 6; // 😁
542
+ setTimeout(() => currentModiFrame = 0, 200);
543
+
544
+ // Show Modi's speech
545
+ showSpeech(modiSpeech, "Mitron!");
546
+ modiSpeech.style.left = `${bat.x + bat.width/2}px`;
547
+ modiSpeech.style.bottom = `${canvas.height - bat.y + 30}px`;
548
+
549
+ // Calculate hit angle based on where ball hits the bat
550
+ const hitPoint = (ball.x - (bat.x + bat.width/2)) / (bat.width/2);
551
+ ball.speedX = hitPoint * 7 * gameSpeed;
552
+ ball.speedY = -Math.abs(ball.speedY);
553
+
554
+ // Increase score for hitting
555
+ score += 10;
556
+ updateScoreboard();
557
+ }
558
+
559
+ // Ball out of bounds (bottom)
560
+ if (ball.y - ball.radius > canvas.height) {
561
+ ball.active = false;
562
+
563
+ // Change Modi's expression to angry
564
+ currentModiFrame = 4; // 😑
565
+
566
+ // Show Kejriwal's taunt
567
+ const randomMissPhrase = sounds.miss[Math.floor(Math.random() * sounds.miss.length)];
568
+ showSpeech(kejriwalSpeech, randomMissPhrase);
569
+ kejriwalSpeech.style.left = `${ball.x}px`;
570
+ kejriwalSpeech.style.top = `${ball.y - 50}px`;
571
+
572
+ // Check if game over (3 missed balls)
573
+ if (ballsFaced >= 3) {
574
+ gameOver();
575
+ } else {
576
+ setTimeout(() => {
577
+ currentModiFrame = 0;
578
+ resetBall();
579
+ }, 1000);
580
+ }
581
+ }
582
+
583
+ // Collision detection
584
+ collisionDetection();
585
+ }
586
+
587
+ requestAnimationFrame(gameLoop);
588
+ }
589
+
590
+ // Game over function
591
+ function gameOver() {
592
+ gameActive = false;
593
+ finalScore.textContent = `Your score: ${score}`;
594
+
595
+ // Display appropriate message based on score
596
+ let message = "Try Again!";
597
+ if (score > 1500) message = "Supreme Leader! πŸ†";
598
+ else if (score > 1000) message = "56-inch Performance! πŸ‘";
599
+ else if (score > 500) message = "Good Effort Mitron! πŸ‘";
600
+
601
+ document.querySelector("#gameOver p").textContent = `Your score: ${score} - ${message}`;
602
+ gameOverScreen.style.display = 'block';
603
+ }
604
+
605
+ // Keyboard controls
606
+ const keys = {
607
+ ArrowLeft: false,
608
+ ArrowRight: false
609
+ };
610
+
611
+ document.addEventListener('keydown', (e) => {
612
+ if (e.key in keys) {
613
+ keys[e.key] = true;
614
+ lastDirection = e.key === 'ArrowLeft' ? 'left' : 'right';
615
+ e.preventDefault();
616
+ }
617
+
618
+ // Space bar to start/restart game
619
+ if (e.key === ' ' && !gameActive) {
620
+ init();
621
+ }
622
+
623
+ // Enter key to start/restart game
624
+ if (e.key === 'Enter' && !gameActive) {
625
+ init();
626
+ }
627
+ });
628
+
629
+ document.addEventListener('keyup', (e) => {
630
+ if (e.key in keys) {
631
+ keys[e.key] = false;
632
+ e.preventDefault();
633
+ }
634
+ });
635
+
636
+ // Handle bat movement
637
+ function handleBatMovement() {
638
+ if (keys.ArrowLeft && bat.x > 0) {
639
+ bat.x -= bat.speed;
640
+ }
641
+ if (keys.ArrowRight && bat.x < canvas.width - bat.width) {
642
+ bat.x += bat.speed;
643
+ }
644
+ }
645
+
646
+ // Input handler for restart button
647
+ restartBtn.addEventListener('click', init);
648
+
649
+ // Bat movement interval
650
+ setInterval(handleBatMovement, 16);
651
+
652
+ // Start game on any key press
653
+ document.addEventListener('keydown', function firstKeyPress() {
654
+ init();
655
+ document.removeEventListener('keydown', firstKeyPress);
656
+ });
657
+
658
+ // Display start instructions
659
+ gameOverScreen.style.display = 'block';
660
+ finalScore.textContent = "Press any key to start";
661
+ document.querySelector("#gameOver h1").textContent = "Modi vs Kejriwal";
662
+ document.querySelector("#gameOver p").textContent = "Use LEFT and RIGHT arrow keys to defend India!";
663
+ </script>
664
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: absolute; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">This website has been generated by <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
665
+ </html>