cfalk43 commited on
Commit
66e0807
·
verified ·
1 Parent(s): a8baf72

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +781 -19
index.html CHANGED
@@ -1,19 +1,781 @@
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
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Dino Runner Game</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet">
9
+ <style>
10
+ * {
11
+ margin: 0;
12
+ padding: 0;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ body {
17
+ min-height: 100vh;
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
22
+ font-family: 'Press Start 2P', cursive;
23
+ overflow: hidden;
24
+ }
25
+
26
+ header {
27
+ width: 100%;
28
+ padding: 1rem;
29
+ text-align: center;
30
+ background: rgba(255, 255, 255, 0.1);
31
+ backdrop-filter: blur(10px);
32
+ border-bottom: 2px solid rgba(255, 255, 255, 0.2);
33
+ }
34
+
35
+ header a {
36
+ color: #00d4ff;
37
+ text-decoration: none;
38
+ font-size: 0.7rem;
39
+ transition: all 0.3s ease;
40
+ }
41
+
42
+ header a:hover {
43
+ color: #fff;
44
+ text-shadow: 0 0 10px #00d4ff;
45
+ }
46
+
47
+ .game-container {
48
+ display: flex;
49
+ flex-direction: column;
50
+ align-items: center;
51
+ justify-content: center;
52
+ flex: 1;
53
+ padding: 2rem;
54
+ width: 100%;
55
+ max-width: 900px;
56
+ }
57
+
58
+ h1 {
59
+ color: #fff;
60
+ font-size: clamp(1rem, 4vw, 2rem);
61
+ margin-bottom: 1rem;
62
+ text-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
63
+ text-align: center;
64
+ }
65
+
66
+ .score-board {
67
+ display: flex;
68
+ gap: 2rem;
69
+ margin-bottom: 1rem;
70
+ flex-wrap: wrap;
71
+ justify-content: center;
72
+ }
73
+
74
+ .score-item {
75
+ color: #fff;
76
+ font-size: clamp(0.6rem, 2vw, 0.9rem);
77
+ padding: 0.5rem 1rem;
78
+ background: rgba(255, 255, 255, 0.1);
79
+ border-radius: 10px;
80
+ border: 1px solid rgba(255, 255, 255, 0.2);
81
+ }
82
+
83
+ .score-item span {
84
+ color: #00d4ff;
85
+ }
86
+
87
+ #gameCanvas {
88
+ border: 4px solid #00d4ff;
89
+ border-radius: 15px;
90
+ box-shadow: 0 0 30px rgba(0, 212, 255, 0.3),
91
+ inset 0 0 50px rgba(0, 0, 0, 0.5);
92
+ background: linear-gradient(180deg, #87CEEB 0%, #E0F6FF 60%, #90EE90 60%, #228B22 100%);
93
+ max-width: 100%;
94
+ cursor: pointer;
95
+ }
96
+
97
+ .instructions {
98
+ color: rgba(255, 255, 255, 0.7);
99
+ font-size: clamp(0.5rem, 1.5vw, 0.7rem);
100
+ margin-top: 1rem;
101
+ text-align: center;
102
+ line-height: 2;
103
+ }
104
+
105
+ .instructions kbd {
106
+ background: rgba(255, 255, 255, 0.2);
107
+ padding: 0.3rem 0.6rem;
108
+ border-radius: 5px;
109
+ border: 1px solid rgba(255, 255, 255, 0.3);
110
+ }
111
+
112
+ .game-over-overlay {
113
+ position: fixed;
114
+ top: 0;
115
+ left: 0;
116
+ width: 100%;
117
+ height: 100%;
118
+ background: rgba(0, 0, 0, 0.8);
119
+ display: none;
120
+ justify-content: center;
121
+ align-items: center;
122
+ z-index: 100;
123
+ }
124
+
125
+ .game-over-content {
126
+ text-align: center;
127
+ color: #fff;
128
+ padding: 2rem;
129
+ background: linear-gradient(135deg, #1a1a2e, #16213e);
130
+ border-radius: 20px;
131
+ border: 3px solid #00d4ff;
132
+ box-shadow: 0 0 50px rgba(0, 212, 255, 0.5);
133
+ }
134
+
135
+ .game-over-content h2 {
136
+ font-size: clamp(1.5rem, 5vw, 2.5rem);
137
+ margin-bottom: 1rem;
138
+ color: #ff4757;
139
+ }
140
+
141
+ .game-over-content p {
142
+ font-size: clamp(0.7rem, 2vw, 1rem);
143
+ margin-bottom: 1.5rem;
144
+ }
145
+
146
+ .restart-btn {
147
+ font-family: 'Press Start 2P', cursive;
148
+ font-size: clamp(0.6rem, 2vw, 0.9rem);
149
+ padding: 1rem 2rem;
150
+ background: linear-gradient(135deg, #00d4ff, #0099cc);
151
+ color: #fff;
152
+ border: none;
153
+ border-radius: 10px;
154
+ cursor: pointer;
155
+ transition: all 0.3s ease;
156
+ }
157
+
158
+ .restart-btn:hover {
159
+ transform: scale(1.05);
160
+ box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
161
+ }
162
+
163
+ .start-screen {
164
+ position: fixed;
165
+ top: 0;
166
+ left: 0;
167
+ width: 100%;
168
+ height: 100%;
169
+ background: rgba(0, 0, 0, 0.9);
170
+ display: flex;
171
+ justify-content: center;
172
+ align-items: center;
173
+ z-index: 100;
174
+ }
175
+
176
+ .start-content {
177
+ text-align: center;
178
+ color: #fff;
179
+ padding: 2rem;
180
+ }
181
+
182
+ .start-content h2 {
183
+ font-size: clamp(1.5rem, 5vw, 3rem);
184
+ margin-bottom: 2rem;
185
+ color: #00d4ff;
186
+ text-shadow: 0 0 30px rgba(0, 212, 255, 0.7);
187
+ }
188
+
189
+ .dino-art {
190
+ font-size: clamp(3rem, 10vw, 6rem);
191
+ margin-bottom: 2rem;
192
+ animation: bounce 1s infinite;
193
+ }
194
+
195
+ @keyframes bounce {
196
+
197
+ 0%,
198
+ 100% {
199
+ transform: translateY(0);
200
+ }
201
+
202
+ 50% {
203
+ transform: translateY(-20px);
204
+ }
205
+ }
206
+
207
+ .start-btn {
208
+ font-family: 'Press Start 2P', cursive;
209
+ font-size: clamp(0.8rem, 2.5vw, 1.2rem);
210
+ padding: 1.5rem 3rem;
211
+ background: linear-gradient(135deg, #00d4ff, #0099cc);
212
+ color: #fff;
213
+ border: none;
214
+ border-radius: 15px;
215
+ cursor: pointer;
216
+ transition: all 0.3s ease;
217
+ animation: pulse 2s infinite;
218
+ }
219
+
220
+ @keyframes pulse {
221
+
222
+ 0%,
223
+ 100% {
224
+ box-shadow: 0 0 20px rgba(0, 212, 255, 0.5);
225
+ }
226
+
227
+ 50% {
228
+ box-shadow: 0 0 40px rgba(0, 212, 255, 0.8);
229
+ }
230
+ }
231
+
232
+ .start-btn:hover {
233
+ transform: scale(1.1);
234
+ }
235
+
236
+ @media (max-width: 600px) {
237
+ .game-container {
238
+ padding: 1rem;
239
+ }
240
+
241
+ .score-board {
242
+ gap: 1rem;
243
+ }
244
+ }
245
+ </style>
246
+ </head>
247
+
248
+ <body>
249
+ <header>
250
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
251
+ </header>
252
+
253
+ <div class="start-screen" id="startScreen">
254
+ <div class="start-content">
255
+ <h2>🦖 DINO RUNNER 🦖</h2>
256
+ <div class="dino-art">🦕</div>
257
+ <button class="start-btn" id="startBtn">START GAME</button>
258
+ </div>
259
+ </div>
260
+
261
+ <div class="game-container">
262
+ <h1>🦖 DINO RUNNER 🦖</h1>
263
+
264
+ <div class="score-board">
265
+ <div class="score-item">SCORE: <span id="score">0</span></div>
266
+ <div class="score-item">HIGH SCORE: <span id="highScore">0</span></div>
267
+ </div>
268
+
269
+ <canvas id="gameCanvas" width="800" height="300"></canvas>
270
+
271
+ <div class="instructions">
272
+ Press <kbd>SPACE</kbd> or <kbd>↑</kbd> to jump | <kbd>↓</kbd> to duck | <kbd>TAP</kbd> on mobile
273
+ </div>
274
+ </div>
275
+
276
+ <div class="game-over-overlay" id="gameOverOverlay">
277
+ <div class="game-over-content">
278
+ <h2>GAME OVER!</h2>
279
+ <p>Your Score: <span id="finalScore">0</span></p>
280
+ <button class="restart-btn" id="restartBtn">PLAY AGAIN</button>
281
+ </div>
282
+ </div>
283
+
284
+ <script>
285
+ const canvas = document.getElementById('gameCanvas');
286
+ const ctx = canvas.getContext('2d');
287
+ const scoreElement = document.getElementById('score');
288
+ const highScoreElement = document.getElementById('highScore');
289
+ const finalScoreElement = document.getElementById('finalScore');
290
+ const gameOverOverlay = document.getElementById('gameOverOverlay');
291
+ const startScreen = document.getElementById('startScreen');
292
+ const startBtn = document.getElementById('startBtn');
293
+ const restartBtn = document.getElementById('restartBtn');
294
+
295
+ // Responsive canvas
296
+ function resizeCanvas() {
297
+ const maxWidth = Math.min(800, window.innerWidth - 40);
298
+ const ratio = 300 / 800;
299
+ canvas.style.width = maxWidth + 'px';
300
+ canvas.style.height = (maxWidth * ratio) + 'px';
301
+ }
302
+ resizeCanvas();
303
+ window.addEventListener('resize', resizeCanvas);
304
+
305
+ // Game variables
306
+ let gameRunning = false;
307
+ let gameSpeed = 6;
308
+ let score = 0;
309
+ let highScore = localStorage.getItem('dinoHighScore') || 0;
310
+ highScoreElement.textContent = highScore;
311
+
312
+ // Dino
313
+ const dino = {
314
+ x: 50,
315
+ y: 220,
316
+ width: 50,
317
+ height: 60,
318
+ velocityY: 0,
319
+ jumping: false,
320
+ ducking: false,
321
+ duckHeight: 35,
322
+ normalHeight: 60,
323
+ groundY: 220,
324
+ frame: 0,
325
+ frameCount: 0
326
+ };
327
+
328
+ // Obstacles
329
+ let obstacles = [];
330
+ let obstacleTimer = 0;
331
+ const obstacleInterval = 100;
332
+
333
+ // Clouds
334
+ let clouds = [];
335
+
336
+ // Ground
337
+ let groundX = 0;
338
+
339
+ // Physics
340
+ const gravity = 0.8;
341
+ const jumpForce = -15;
342
+
343
+ // Initialize clouds
344
+ function initClouds() {
345
+ clouds = [];
346
+ for (let i = 0; i < 5; i++) {
347
+ clouds.push({
348
+ x: Math.random() * canvas.width,
349
+ y: 30 + Math.random() * 60,
350
+ width: 60 + Math.random() * 40,
351
+ speed: 1 + Math.random()
352
+ });
353
+ }
354
+ }
355
+
356
+ // Draw cloud
357
+ function drawCloud(cloud) {
358
+ ctx.fillStyle = 'rgba(255, 255, 255, 0.8)';
359
+ ctx.beginPath();
360
+ ctx.arc(cloud.x, cloud.y, 20, 0, Math.PI * 2);
361
+ ctx.arc(cloud.x + 25, cloud.y - 10, 25, 0, Math.PI * 2);
362
+ ctx.arc(cloud.x + 50, cloud.y, 20, 0, Math.PI * 2);
363
+ ctx.arc(cloud.x + 25, cloud.y + 5, 22, 0, Math.PI * 2);
364
+ ctx.fill();
365
+ }
366
+
367
+ // Draw dino
368
+ function drawDino() {
369
+ const height = dino.ducking ? dino.duckHeight : dino.normalHeight;
370
+ const y = dino.ducking ? dino.groundY + (dino.normalHeight - dino.duckHeight) : dino.y;
371
+
372
+ // Body
373
+ ctx.fillStyle = '#2d5016';
374
+ ctx.beginPath();
375
+ ctx.roundRect(dino.x, y, dino.width - 10, height, 10);
376
+ ctx.fill();
377
+
378
+ // Head
379
+ ctx.fillStyle = '#3d6b1e';
380
+ if (!dino.ducking) {
381
+ ctx.beginPath();
382
+ ctx.roundRect(dino.x + 15, y - 25, 35, 30, 8);
383
+ ctx.fill();
384
+
385
+ // Eye
386
+ ctx.fillStyle = '#fff';
387
+ ctx.beginPath();
388
+ ctx.arc(dino.x + 40, y - 12, 6, 0, Math.PI * 2);
389
+ ctx.fill();
390
+ ctx.fillStyle = '#000';
391
+ ctx.beginPath();
392
+ ctx.arc(dino.x + 42, y - 12, 3, 0, Math.PI * 2);
393
+ ctx.fill();
394
+
395
+ // Mouth
396
+ ctx.strokeStyle = '#1a3d0c';
397
+ ctx.lineWidth = 2;
398
+ ctx.beginPath();
399
+ ctx.moveTo(dino.x + 45, y - 5);
400
+ ctx.lineTo(dino.x + 50, y - 5);
401
+ ctx.stroke();
402
+ } else {
403
+ // Ducking head
404
+ ctx.beginPath();
405
+ ctx.roundRect(dino.x + 30, y - 5, 30, 20, 5);
406
+ ctx.fill();
407
+
408
+ // Eye when ducking
409
+ ctx.fillStyle = '#fff';
410
+ ctx.beginPath();
411
+ ctx.arc(dino.x + 50, y + 5, 4, 0, Math.PI * 2);
412
+ ctx.fill();
413
+ ctx.fillStyle = '#000';
414
+ ctx.beginPath();
415
+ ctx.arc(dino.x + 51, y + 5, 2, 0, Math.PI * 2);
416
+ ctx.fill();
417
+ }
418
+
419
+ // Legs animation
420
+ ctx.fillStyle = '#2d5016';
421
+ dino.frameCount++;
422
+ if (dino.frameCount > 5) {
423
+ dino.frame = (dino.frame + 1) % 2;
424
+ dino.frameCount = 0;
425
+ }
426
+
427
+ if (!dino.jumping) {
428
+ const legOffset = dino.frame === 0 ? 5 : -5;
429
+ ctx.fillRect(dino.x + 8, y + height - 5, 8, 15 + legOffset);
430
+ ctx.fillRect(dino.x + 25, y + height - 5, 8, 15 - legOffset);
431
+ } else {
432
+ ctx.fillRect(dino.x + 8, y + height - 5, 8, 12);
433
+ ctx.fillRect(dino.x + 25, y + height - 5, 8, 12);
434
+ }
435
+
436
+ // Tail
437
+ ctx.fillStyle = '#3d6b1e';
438
+ ctx.beginPath();
439
+ ctx.moveTo(dino.x, y + 20);
440
+ ctx.lineTo(dino.x - 20, y + 15);
441
+ ctx.lineTo(dino.x, y + 35);
442
+ ctx.fill();
443
+ }
444
+
445
+ // Draw cactus obstacle
446
+ function drawCactus(obstacle) {
447
+ ctx.fillStyle = '#228B22';
448
+
449
+ // Main stem
450
+ ctx.beginPath();
451
+ ctx.roundRect(obstacle.x + 10, obstacle.y, 20, obstacle.height, 5);
452
+ ctx.fill();
453
+
454
+ // Left arm
455
+ ctx.beginPath();
456
+ ctx.roundRect(obstacle.x, obstacle.y + 15, 12, 25, 4);
457
+ ctx.fill();
458
+ ctx.beginPath();
459
+ ctx.roundRect(obstacle.x, obstacle.y + 10, 8, 15, 3);
460
+ ctx.fill();
461
+
462
+ // Right arm
463
+ ctx.beginPath();
464
+ ctx.roundRect(obstacle.x + 28, obstacle.y + 25, 12, 20, 4);
465
+ ctx.fill();
466
+ ctx.beginPath();
467
+ ctx.roundRect(obstacle.x + 32, obstacle.y + 20, 8, 12, 3);
468
+ ctx.fill();
469
+
470
+ // Spikes
471
+ ctx.fillStyle = '#1a6b1a';
472
+ for (let i = 0; i < 5; i++) {
473
+ ctx.beginPath();
474
+ ctx.arc(obstacle.x + 20, obstacle.y + i * 12, 2, 0, Math.PI * 2);
475
+ ctx.fill();
476
+ }
477
+ }
478
+
479
+ // Draw bird obstacle
480
+ function drawBird(obstacle) {
481
+ ctx.fillStyle = '#8B4513';
482
+
483
+ // Body
484
+ ctx.beginPath();
485
+ ctx.ellipse(obstacle.x + 20, obstacle.y + 15, 20, 12, 0, 0, Math.PI * 2);
486
+ ctx.fill();
487
+
488
+ // Head
489
+ ctx.beginPath();
490
+ ctx.arc(obstacle.x + 40, obstacle.y + 10, 10, 0, Math.PI * 2);
491
+ ctx.fill();
492
+
493
+ // Beak
494
+ ctx.fillStyle = '#FFA500';
495
+ ctx.beginPath();
496
+ ctx.moveTo(obstacle.x + 50, obstacle.y + 10);
497
+ ctx.lineTo(obstacle.x + 60, obstacle.y + 12);
498
+ ctx.lineTo(obstacle.x + 50, obstacle.y + 14);
499
+ ctx.fill();
500
+
501
+ // Eye
502
+ ctx.fillStyle = '#fff';
503
+ ctx.beginPath();
504
+ ctx.arc(obstacle.x + 43, obstacle.y + 8, 4, 0, Math.PI * 2);
505
+ ctx.fill();
506
+ ctx.fillStyle = '#000';
507
+ ctx.beginPath();
508
+ ctx.arc(obstacle.x + 44, obstacle.y + 8, 2, 0, Math.PI * 2);
509
+ ctx.fill();
510
+
511
+ // Wings animation
512
+ ctx.fillStyle = '#6B3E26';
513
+ const wingY = Math.sin(Date.now() / 100) * 10;
514
+ ctx.beginPath();
515
+ ctx.moveTo(obstacle.x + 10, obstacle.y + 15);
516
+ ctx.lineTo(obstacle.x - 10, obstacle.y + wingY);
517
+ ctx.lineTo(obstacle.x + 20, obstacle.y + 15);
518
+ ctx.fill();
519
+ }
520
+
521
+ // Draw ground
522
+ function drawGround() {
523
+ ctx.fillStyle = '#8B4513';
524
+ ctx.fillRect(0, 280, canvas.width, 20);
525
+
526
+ ctx.fillStyle = '#654321';
527
+ groundX -= gameSpeed;
528
+ if (groundX <= -20) groundX = 0;
529
+
530
+ for (let i = groundX; i < canvas.width; i += 20) {
531
+ ctx.fillRect(i, 282, 15, 3);
532
+ ctx.fillRect(i + 7, 288, 10, 2);
533
+ }
534
+
535
+ // Grass
536
+ ctx.fillStyle = '#228B22';
537
+ ctx.fillRect(0, 275, canvas.width, 5);
538
+ }
539
+
540
+ // Spawn obstacle
541
+ function spawnObstacle() {
542
+ const type = Math.random() > 0.7 ? 'bird' : 'cactus';
543
+ const obstacle = {
544
+ x: canvas.width,
545
+ type: type,
546
+ width: type === 'cactus' ? 40 : 60,
547
+ height: type === 'cactus' ? 50 + Math.random() * 20 : 30
548
+ };
549
+
550
+ if (type === 'cactus') {
551
+ obstacle.y = 280 - obstacle.height;
552
+ } else {
553
+ obstacle.y = Math.random() > 0.5 ? 180 : 230;
554
+ }
555
+
556
+ obstacles.push(obstacle);
557
+ }
558
+
559
+ // Check collision
560
+ function checkCollision() {
561
+ const dinoHeight = dino.ducking ? dino.duckHeight : dino.normalHeight;
562
+ const dinoY = dino.ducking ? dino.groundY + (dino.normalHeight - dino.duckHeight) : dino.y;
563
+
564
+ for (let obstacle of obstacles) {
565
+ if (dino.x + dino.width - 15 > obstacle.x &&
566
+ dino.x + 10 < obstacle.x + obstacle.width &&
567
+ dinoY + dinoHeight > obstacle.y &&
568
+ dinoY < obstacle.y + obstacle.height) {
569
+ return true;
570
+ }
571
+ }
572
+ return false;
573
+ }
574
+
575
+ // Game over
576
+ function gameOver() {
577
+ gameRunning = false;
578
+ finalScoreElement.textContent = score;
579
+
580
+ if (score > highScore) {
581
+ highScore = score;
582
+ localStorage.setItem('dinoHighScore', highScore);
583
+ highScoreElement.textContent = highScore;
584
+ }
585
+
586
+ gameOverOverlay.style.display = 'flex';
587
+ }
588
+
589
+ // Reset game
590
+ function resetGame() {
591
+ score = 0;
592
+ gameSpeed = 6;
593
+ obstacles = [];
594
+ obstacleTimer = 0;
595
+ dino.y = dino.groundY;
596
+ dino.velocityY = 0;
597
+ dino.jumping = false;
598
+ dino.ducking = false;
599
+ initClouds();
600
+ gameOverOverlay.style.display = 'none';
601
+ gameRunning = true;
602
+ gameLoop();
603
+ }
604
+
605
+ // Update game
606
+ function update() {
607
+ // Dino physics
608
+ if (dino.jumping) {
609
+ dino.velocityY += gravity;
610
+ dino.y += dino.velocityY;
611
+
612
+ if (dino.y >= dino.groundY) {
613
+ dino.y = dino.groundY;
614
+ dino.jumping = false;
615
+ dino.velocityY = 0;
616
+ }
617
+ }
618
+
619
+ // Update obstacles
620
+ obstacleTimer++;
621
+ if (obstacleTimer >= obstacleInterval - Math.min(score / 10, 50)) {
622
+ spawnObstacle();
623
+ obstacleTimer = 0;
624
+ }
625
+
626
+ for (let i = obstacles.length - 1; i >= 0; i--) {
627
+ obstacles[i].x -= gameSpeed;
628
+
629
+ if (obstacles[i].x + obstacles[i].width < 0) {
630
+ obstacles.splice(i, 1);
631
+ score++;
632
+ scoreElement.textContent = score;
633
+ }
634
+ }
635
+
636
+ // Update clouds
637
+ for (let cloud of clouds) {
638
+ cloud.x -= cloud.speed;
639
+ if (cloud.x + cloud.width < 0) {
640
+ cloud.x = canvas.width + 50;
641
+ cloud.y = 30 + Math.random() * 60;
642
+ }
643
+ }
644
+
645
+ // Increase speed
646
+ if (score > 0 && score % 10 === 0) {
647
+ gameSpeed = 6 + Math.floor(score / 10) * 0.5;
648
+ }
649
+
650
+ // Check collision
651
+ if (checkCollision()) {
652
+ gameOver();
653
+ }
654
+ }
655
+
656
+ // Draw game
657
+ function draw() {
658
+ // Sky gradient
659
+ const gradient = ctx.createLinearGradient(0, 0, 0, 280);
660
+ gradient.addColorStop(0, '#87CEEB');
661
+ gradient.addColorStop(0.6, '#E0F6FF');
662
+ gradient.addColorStop(0.6, '#90EE90');
663
+ gradient.addColorStop(1, '#228B22');
664
+ ctx.fillStyle = gradient;
665
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
666
+
667
+ // Sun
668
+ ctx.fillStyle = '#FFD700';
669
+ ctx.beginPath();
670
+ ctx.arc(700, 50, 30, 0, Math.PI * 2);
671
+ ctx.fill();
672
+ ctx.fillStyle = 'rgba(255, 215, 0, 0.3)';
673
+ ctx.beginPath();
674
+ ctx.arc(700, 50, 45, 0, Math.PI * 2);
675
+ ctx.fill();
676
+
677
+ // Clouds
678
+ for (let cloud of clouds) {
679
+ drawCloud(cloud);
680
+ }
681
+
682
+ // Ground
683
+ drawGround();
684
+
685
+ // Obstacles
686
+ for (let obstacle of obstacles) {
687
+ if (obstacle.type === 'cactus') {
688
+ drawCactus(obstacle);
689
+ } else {
690
+ drawBird(obstacle);
691
+ }
692
+ }
693
+
694
+ // Dino
695
+ drawDino();
696
+ }
697
+
698
+ // Game loop
699
+ function gameLoop() {
700
+ if (!gameRunning) return;
701
+
702
+ update();
703
+ draw();
704
+ requestAnimationFrame(gameLoop);
705
+ }
706
+
707
+ // Controls
708
+ function jump() {
709
+ if (!dino.jumping && !dino.ducking) {
710
+ dino.jumping = true;
711
+ dino.velocityY = jumpForce;
712
+ }
713
+ }
714
+
715
+ function duck(isDucking) {
716
+ if (!dino.jumping) {
717
+ dino.ducking = isDucking;
718
+ }
719
+ }
720
+
721
+ // Event listeners
722
+ document.addEventListener('keydown', (e) => {
723
+ if (!gameRunning) return;
724
+
725
+ if (e.code === 'Space' || e.code === 'ArrowUp') {
726
+ e.preventDefault();
727
+ jump();
728
+ }
729
+ if (e.code === 'ArrowDown') {
730
+ e.preventDefault();
731
+ duck(true);
732
+ }
733
+ });
734
+
735
+ document.addEventListener('keyup', (e) => {
736
+ if (e.code === 'ArrowDown') {
737
+ duck(false);
738
+ }
739
+ });
740
+
741
+ // Touch controls
742
+ canvas.addEventListener('touchstart', (e) => {
743
+ e.preventDefault();
744
+ if (gameRunning) {
745
+ const touch = e.touches[0];
746
+ const rect = canvas.getBoundingClientRect();
747
+ const y = touch.clientY - rect.top;
748
+
749
+ if (y > rect.height / 2) {
750
+ duck(true);
751
+ } else {
752
+ jump();
753
+ }
754
+ }
755
+ });
756
+
757
+ canvas.addEventListener('touchend', (e) => {
758
+ duck(false);
759
+ });
760
+
761
+ canvas.addEventListener('click', () => {
762
+ if (gameRunning) {
763
+ jump();
764
+ }
765
+ });
766
+
767
+ // Start and restart buttons
768
+ startBtn.addEventListener('click', () => {
769
+ startScreen.style.display = 'none';
770
+ resetGame();
771
+ });
772
+
773
+ restartBtn.addEventListener('click', resetGame);
774
+
775
+ // Initialize
776
+ initClouds();
777
+ draw();
778
+ </script>
779
+ </body>
780
+
781
+ </html>