soumalya-iitj commited on
Commit
6fc1cde
·
verified ·
1 Parent(s): 2afacd5

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +681 -19
index.html CHANGED
@@ -1,19 +1,681 @@
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
+ <meta name="description" content="Interactive Embodied AI Autonomous Vehicle Simulator - Real-time AI decision making and navigation">
7
+ <meta name="keywords" content="AI, autonomous vehicles, simulation, embodied AI, robotics, machine learning">
8
+ <meta name="author" content="Embodied AI Research">
9
+ <title>🚗 Embodied AI - Autonomous Vehicle Simulator</title>
10
+
11
+ <!-- Open Graph Meta Tags for Social Sharing -->
12
+ <meta property="og:title" content="Embodied AI Vehicle Simulator">
13
+ <meta property="og:description" content="Interactive demonstration of autonomous vehicle AI with real-time decision making">
14
+ <meta property="og:type" content="website">
15
+ <meta property="og:image" content="https://via.placeholder.com/1200x630/667eea/ffffff?text=Embodied+AI+Vehicle+Simulator">
16
+
17
+ <!-- Favicon -->
18
+ <link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🚗</text></svg>">
19
+
20
+ <style>
21
+ * {
22
+ margin: 0;
23
+ padding: 0;
24
+ box-sizing: border-box;
25
+ }
26
+
27
+ body {
28
+ font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', sans-serif;
29
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
30
+ min-height: 100vh;
31
+ display: flex;
32
+ flex-direction: column;
33
+ color: white;
34
+ overflow-x: hidden;
35
+ }
36
+
37
+ .header {
38
+ background: rgba(0, 0, 0, 0.3);
39
+ padding: 20px;
40
+ text-align: center;
41
+ backdrop-filter: blur(10px);
42
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
43
+ position: relative;
44
+ }
45
+
46
+ .header h1 {
47
+ font-size: clamp(1.8rem, 4vw, 2.5rem);
48
+ margin-bottom: 10px;
49
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
50
+ background: linear-gradient(45deg, #fff, #e0e0e0);
51
+ -webkit-background-clip: text;
52
+ -webkit-text-fill-color: transparent;
53
+ background-clip: text;
54
+ }
55
+
56
+ .header p {
57
+ font-size: clamp(0.9rem, 2.5vw, 1.1rem);
58
+ opacity: 0.9;
59
+ }
60
+
61
+ .hf-badge {
62
+ position: absolute;
63
+ top: 10px;
64
+ right: 20px;
65
+ background: rgba(255, 255, 255, 0.2);
66
+ padding: 5px 10px;
67
+ border-radius: 15px;
68
+ font-size: 0.8rem;
69
+ backdrop-filter: blur(5px);
70
+ }
71
+
72
+ .main-container {
73
+ display: flex;
74
+ flex: 1;
75
+ gap: 20px;
76
+ padding: 20px;
77
+ max-width: 1400px;
78
+ margin: 0 auto;
79
+ width: 100%;
80
+ }
81
+
82
+ .simulation-area {
83
+ flex: 1;
84
+ background: rgba(255, 255, 255, 0.1);
85
+ border-radius: 15px;
86
+ padding: 20px;
87
+ backdrop-filter: blur(10px);
88
+ border: 1px solid rgba(255, 255, 255, 0.2);
89
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
90
+ }
91
+
92
+ .canvas-container {
93
+ position: relative;
94
+ width: 100%;
95
+ height: 600px;
96
+ background: #1a1a2e;
97
+ border-radius: 10px;
98
+ overflow: hidden;
99
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
100
+ border: 2px solid rgba(255, 255, 255, 0.1);
101
+ }
102
+
103
+ #simulationCanvas {
104
+ width: 100%;
105
+ height: 100%;
106
+ display: block;
107
+ cursor: crosshair;
108
+ }
109
+
110
+ .controls-panel {
111
+ width: 320px;
112
+ background: rgba(255, 255, 255, 0.1);
113
+ border-radius: 15px;
114
+ padding: 20px;
115
+ backdrop-filter: blur(10px);
116
+ border: 1px solid rgba(255, 255, 255, 0.2);
117
+ height: fit-content;
118
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
119
+ }
120
+
121
+ .control-section {
122
+ margin-bottom: 25px;
123
+ }
124
+
125
+ .control-section h3 {
126
+ font-size: 1.2rem;
127
+ margin-bottom: 15px;
128
+ color: #fff;
129
+ border-bottom: 2px solid rgba(255, 255, 255, 0.3);
130
+ padding-bottom: 8px;
131
+ display: flex;
132
+ align-items: center;
133
+ gap: 8px;
134
+ }
135
+
136
+ .control-group {
137
+ margin-bottom: 15px;
138
+ }
139
+
140
+ .control-group label {
141
+ display: block;
142
+ margin-bottom: 8px;
143
+ font-weight: 500;
144
+ color: #e0e0e0;
145
+ font-size: 0.9rem;
146
+ }
147
+
148
+ .control-group input, .control-group select {
149
+ width: 100%;
150
+ padding: 10px 12px;
151
+ border: none;
152
+ border-radius: 8px;
153
+ background: rgba(255, 255, 255, 0.2);
154
+ color: white;
155
+ font-size: 14px;
156
+ transition: background 0.3s ease;
157
+ }
158
+
159
+ .control-group input:focus, .control-group select:focus {
160
+ outline: 2px solid rgba(255, 255, 255, 0.5);
161
+ background: rgba(255, 255, 255, 0.3);
162
+ }
163
+
164
+ .control-group input::placeholder {
165
+ color: rgba(255, 255, 255, 0.6);
166
+ }
167
+
168
+ .slider-container {
169
+ display: flex;
170
+ align-items: center;
171
+ gap: 10px;
172
+ }
173
+
174
+ .slider-container input[type="range"] {
175
+ flex: 1;
176
+ }
177
+
178
+ .slider-value {
179
+ background: rgba(0, 0, 0, 0.3);
180
+ padding: 4px 8px;
181
+ border-radius: 4px;
182
+ font-size: 0.8rem;
183
+ min-width: 40px;
184
+ text-align: center;
185
+ }
186
+
187
+ .btn {
188
+ width: 100%;
189
+ padding: 12px;
190
+ border: none;
191
+ border-radius: 8px;
192
+ font-size: 16px;
193
+ font-weight: 600;
194
+ cursor: pointer;
195
+ transition: all 0.3s ease;
196
+ margin-bottom: 10px;
197
+ position: relative;
198
+ overflow: hidden;
199
+ }
200
+
201
+ .btn::before {
202
+ content: '';
203
+ position: absolute;
204
+ top: 0;
205
+ left: -100%;
206
+ width: 100%;
207
+ height: 100%;
208
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
209
+ transition: left 0.5s;
210
+ }
211
+
212
+ .btn:hover::before {
213
+ left: 100%;
214
+ }
215
+
216
+ .btn-primary {
217
+ background: linear-gradient(45deg, #4CAF50, #45a049);
218
+ color: white;
219
+ box-shadow: 0 4px 15px rgba(76, 175, 80, 0.3);
220
+ }
221
+
222
+ .btn-secondary {
223
+ background: linear-gradient(45deg, #2196F3, #1976D2);
224
+ color: white;
225
+ box-shadow: 0 4px 15px rgba(33, 150, 243, 0.3);
226
+ }
227
+
228
+ .btn-danger {
229
+ background: linear-gradient(45deg, #f44336, #d32f2f);
230
+ color: white;
231
+ box-shadow: 0 4px 15px rgba(244, 67, 54, 0.3);
232
+ }
233
+
234
+ .btn:hover {
235
+ transform: translateY(-2px);
236
+ box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
237
+ }
238
+
239
+ .btn:active {
240
+ transform: translateY(0);
241
+ }
242
+
243
+ .btn:disabled {
244
+ opacity: 0.6;
245
+ cursor: not-allowed;
246
+ transform: none;
247
+ }
248
+
249
+ .stats {
250
+ background: rgba(0, 0, 0, 0.3);
251
+ padding: 15px;
252
+ border-radius: 8px;
253
+ margin-top: 15px;
254
+ border: 1px solid rgba(255, 255, 255, 0.1);
255
+ }
256
+
257
+ .stats h4 {
258
+ margin-bottom: 12px;
259
+ color: #fff;
260
+ font-size: 1.1rem;
261
+ }
262
+
263
+ .stat-item {
264
+ display: flex;
265
+ justify-content: space-between;
266
+ margin-bottom: 8px;
267
+ font-size: 14px;
268
+ padding: 4px 0;
269
+ }
270
+
271
+ .stat-label {
272
+ color: #ccc;
273
+ }
274
+
275
+ .stat-value {
276
+ color: #4CAF50;
277
+ font-weight: 600;
278
+ font-family: monospace;
279
+ }
280
+
281
+ .ai-info {
282
+ background: rgba(0, 0, 0, 0.3);
283
+ padding: 15px;
284
+ border-radius: 8px;
285
+ margin-top: 15px;
286
+ font-size: 13px;
287
+ line-height: 1.5;
288
+ border: 1px solid rgba(255, 255, 255, 0.1);
289
+ }
290
+
291
+ .ai-info h4 {
292
+ margin-bottom: 10px;
293
+ color: #fff;
294
+ }
295
+
296
+ .ai-info ul {
297
+ margin-left: 15px;
298
+ margin-top: 8px;
299
+ }
300
+
301
+ .ai-info li {
302
+ margin-bottom: 4px;
303
+ color: #e0e0e0;
304
+ }
305
+
306
+ .current-decision {
307
+ background: rgba(76, 175, 80, 0.2);
308
+ padding: 8px;
309
+ border-radius: 4px;
310
+ margin: 10px 0;
311
+ font-family: monospace;
312
+ font-size: 12px;
313
+ border-left: 3px solid #4CAF50;
314
+ }
315
+
316
+ .legend {
317
+ display: flex;
318
+ flex-wrap: wrap;
319
+ gap: 15px;
320
+ margin-top: 15px;
321
+ padding: 10px;
322
+ background: rgba(0, 0, 0, 0.2);
323
+ border-radius: 8px;
324
+ }
325
+
326
+ .legend-item {
327
+ display: flex;
328
+ align-items: center;
329
+ gap: 8px;
330
+ font-size: 12px;
331
+ }
332
+
333
+ .legend-color {
334
+ width: 16px;
335
+ height: 16px;
336
+ border-radius: 50%;
337
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
338
+ }
339
+
340
+ .footer {
341
+ background: rgba(0, 0, 0, 0.3);
342
+ padding: 15px;
343
+ text-align: center;
344
+ backdrop-filter: blur(10px);
345
+ border-top: 1px solid rgba(255, 255, 255, 0.1);
346
+ font-size: 0.9rem;
347
+ color: rgba(255, 255, 255, 0.8);
348
+ }
349
+
350
+ .footer a {
351
+ color: #4CAF50;
352
+ text-decoration: none;
353
+ }
354
+
355
+ .footer a:hover {
356
+ text-decoration: underline;
357
+ }
358
+
359
+ /* Mobile Responsive */
360
+ @media (max-width: 768px) {
361
+ .main-container {
362
+ flex-direction: column;
363
+ padding: 10px;
364
+ }
365
+
366
+ .controls-panel {
367
+ width: 100%;
368
+ }
369
+
370
+ .canvas-container {
371
+ height: 400px;
372
+ }
373
+
374
+ .header {
375
+ padding: 15px;
376
+ }
377
+
378
+ .hf-badge {
379
+ position: static;
380
+ margin-top: 10px;
381
+ display: inline-block;
382
+ }
383
+ }
384
+
385
+ /* Loading Animation */
386
+ .loading {
387
+ display: flex;
388
+ justify-content: center;
389
+ align-items: center;
390
+ position: absolute;
391
+ top: 0;
392
+ left: 0;
393
+ right: 0;
394
+ bottom: 0;
395
+ background: rgba(26, 26, 46, 0.9);
396
+ color: white;
397
+ font-size: 18px;
398
+ }
399
+
400
+ .loading::after {
401
+ content: '';
402
+ width: 40px;
403
+ height: 40px;
404
+ border: 4px solid rgba(255, 255, 255, 0.3);
405
+ border-top: 4px solid #4CAF50;
406
+ border-radius: 50%;
407
+ animation: spin 1s linear infinite;
408
+ margin-left: 15px;
409
+ }
410
+
411
+ @keyframes spin {
412
+ 0% { transform: rotate(0deg); }
413
+ 100% { transform: rotate(360deg); }
414
+ }
415
+
416
+ /* Pulse animation for status indicators */
417
+ .pulse {
418
+ animation: pulse 2s infinite;
419
+ }
420
+
421
+ @keyframes pulse {
422
+ 0% { opacity: 1; }
423
+ 50% { opacity: 0.5; }
424
+ 100% { opacity: 1; }
425
+ }
426
+ </style>
427
+ </head>
428
+ <body>
429
+ <div class="header">
430
+ <div class="hf-badge">🤗 Hugging Face Space</div>
431
+ <h1>🚗 Embodied AI Vehicle Simulator</h1>
432
+ <p>Interactive autonomous vehicle navigation with real-time AI decision making</p>
433
+ </div>
434
+
435
+ <div class="main-container">
436
+ <div class="simulation-area">
437
+ <div class="canvas-container">
438
+ <canvas id="simulationCanvas"></canvas>
439
+ <div class="loading" id="loadingIndicator">
440
+ Initializing AI System...
441
+ </div>
442
+ </div>
443
+
444
+ <div class="legend">
445
+ <div class="legend-item">
446
+ <div class="legend-color" style="background: #4CAF50;"></div>
447
+ <span>Autonomous Vehicle</span>
448
+ </div>
449
+ <div class="legend-item">
450
+ <div class="legend-color" style="background: #f44336;"></div>
451
+ <span>Obstacles</span>
452
+ </div>
453
+ <div class="legend-item">
454
+ <div class="legend-color" style="background: #2196F3;"></div>
455
+ <span>Target Destinations</span>
456
+ </div>
457
+ <div class="legend-item">
458
+ <div class="legend-color" style="background: #FFC107;"></div>
459
+ <span>LiDAR Sensors</span>
460
+ </div>
461
+ </div>
462
+ </div>
463
+
464
+ <div class="controls-panel">
465
+ <div class="control-section">
466
+ <h3>🎮 Simulation Controls</h3>
467
+ <button class="btn btn-primary" id="startBtn">▶️ Start Simulation</button>
468
+ <button class="btn btn-secondary" id="pauseBtn" disabled>⏸️ Pause</button>
469
+ <button class="btn btn-danger" id="resetBtn">🔄 Reset</button>
470
+ </div>
471
+
472
+ <div class="control-section">
473
+ <h3>⚙️ AI Parameters</h3>
474
+ <div class="control-group">
475
+ <label>Vehicle Speed</label>
476
+ <div class="slider-container">
477
+ <input type="range" id="speedSlider" min="0" max="5" value="2" step="0.5">
478
+ <span class="slider-value" id="speedValue">2.0</span>
479
+ </div>
480
+ </div>
481
+ <div class="control-group">
482
+ <label>Sensor Range</label>
483
+ <div class="slider-container">
484
+ <input type="range" id="sensorRange" min="50" max="200" value="100" step="10">
485
+ <span class="slider-value" id="sensorValue">100</span>
486
+ </div>
487
+ </div>
488
+ <div class="control-group">
489
+ <label>AI Behavior</label>
490
+ <select id="behaviorSelect">
491
+ <option value="cautious">🐌 Cautious</option>
492
+ <option value="normal" selected>🚗 Normal</option>
493
+ <option value="aggressive">🏎️ Aggressive</option>
494
+ </select>
495
+ </div>
496
+ </div>
497
+
498
+ <div class="control-section">
499
+ <h3>🏭 Environment</h3>
500
+ <button class="btn btn-secondary" id="addObstacleBtn">➕ Add Obstacle</button>
501
+ <button class="btn btn-secondary" id="addTargetBtn">🎯 Add Target</button>
502
+ <button class="btn btn-danger" id="clearBtn">🗑️ Clear All</button>
503
+ </div>
504
+
505
+ <div class="stats">
506
+ <h4>📊 Performance Metrics</h4>
507
+ <div class="stat-item">
508
+ <span class="stat-label">Distance Traveled:</span>
509
+ <span class="stat-value" id="distanceTraveled">0m</span>
510
+ </div>
511
+ <div class="stat-item">
512
+ <span class="stat-label">Targets Reached:</span>
513
+ <span class="stat-value" id="targetsReached">0</span>
514
+ </div>
515
+ <div class="stat-item">
516
+ <span class="stat-label">Obstacles Avoided:</span>
517
+ <span class="stat-value" id="obstaclesAvoided">0</span>
518
+ </div>
519
+ <div class="stat-item">
520
+ <span class="stat-label">AI Decisions/sec:</span>
521
+ <span class="stat-value pulse" id="decisionsPerSec">0</span>
522
+ </div>
523
+ </div>
524
+
525
+ <div class="ai-info">
526
+ <h4>🧠 AI Decision Engine</h4>
527
+ <div class="current-decision" id="currentDecision">System initializing...</div>
528
+
529
+ <p><strong>Embodied AI Features:</strong></p>
530
+ <ul>
531
+ <li>Real-time sensor processing</li>
532
+ <li>Dynamic path planning</li>
533
+ <li>Multi-objective optimization</li>
534
+ <li>Behavioral adaptation</li>
535
+ <li>Environmental coupling</li>
536
+ </ul>
537
+ </div>
538
+ </div>
539
+ </div>
540
+
541
+ <div class="footer">
542
+ <p>
543
+ Built with ❤️ for the AI community •
544
+ <a href="https://huggingface.co/spaces" target="_blank">Hugging Face Spaces</a> •
545
+ Click to add targets, Shift+Click for obstacles
546
+ </p>
547
+ </div>
548
+
549
+ <script>
550
+ // Enhanced simulator with better performance and mobile support
551
+ const canvas = document.getElementById('simulationCanvas');
552
+ const ctx = canvas.getContext('2d');
553
+ const loadingIndicator = document.getElementById('loadingIndicator');
554
+
555
+ // Performance optimization
556
+ let devicePixelRatio = window.devicePixelRatio || 1;
557
+
558
+ function resizeCanvas() {
559
+ const container = canvas.parentElement;
560
+ const rect = container.getBoundingClientRect();
561
+
562
+ canvas.width = rect.width * devicePixelRatio;
563
+ canvas.height = rect.height * devicePixelRatio;
564
+ canvas.style.width = rect.width + 'px';
565
+ canvas.style.height = rect.height + 'px';
566
+
567
+ ctx.scale(devicePixelRatio, devicePixelRatio);
568
+ }
569
+
570
+ resizeCanvas();
571
+ window.addEventListener('resize', resizeCanvas);
572
+
573
+ // Simulation state
574
+ let isRunning = false;
575
+ let isPaused = false;
576
+ let animationId = null;
577
+ let lastTime = 0;
578
+ let decisionCount = 0;
579
+ let lastDecisionTime = 0;
580
+ let frameCount = 0;
581
+
582
+ // Enhanced Vehicle class with better AI
583
+ class AutonomousVehicle {
584
+ constructor(x, y) {
585
+ this.x = x;
586
+ this.y = y;
587
+ this.vx = 0;
588
+ this.vy = 0;
589
+ this.angle = 0;
590
+ this.speed = 2;
591
+ this.maxSpeed = 5;
592
+ this.size = 15;
593
+ this.sensorRange = 100;
594
+ this.sensors = [];
595
+ this.path = [];
596
+ this.currentTarget = null;
597
+ this.distanceTraveled = 0;
598
+ this.lastX = x;
599
+ this.lastY = y;
600
+ this.behavior = 'normal';
601
+ this.avoidanceVector = { x: 0, y: 0 };
602
+ this.stuckCounter = 0;
603
+ this.lastPosition = { x: x, y: y };
604
+ this.wanderAngle = 0;
605
+ }
606
+
607
+ updateSensors() {
608
+ this.sensors = [];
609
+ const numSensors = 12; // Increased for better detection
610
+
611
+ for (let i = 0; i < numSensors; i++) {
612
+ const angle = (i / numSensors) * 2 * Math.PI;
613
+ const endX = this.x + Math.cos(angle) * this.sensorRange;
614
+ const endY = this.y + Math.sin(angle) * this.sensorRange;
615
+
616
+ let distance = this.sensorRange;
617
+ let hitObstacle = false;
618
+
619
+ // Check collision with obstacles
620
+ for (let obstacle of obstacles) {
621
+ const dx = obstacle.x - this.x;
622
+ const dy = obstacle.y - this.y;
623
+ const distToObstacle = Math.sqrt(dx * dx + dy * dy);
624
+
625
+ if (distToObstacle > 0) {
626
+ const angleToObstacle = Math.atan2(dy, dx);
627
+ let angleDiff = Math.abs(angle - angleToObstacle);
628
+ if (angleDiff > Math.PI) angleDiff = 2 * Math.PI - angleDiff;
629
+
630
+ const detectionCone = 0.3; // Wider detection cone
631
+ if (angleDiff < detectionCone) {
632
+ const actualDistance = Math.max(0, distToObstacle - obstacle.size - 5);
633
+ if (actualDistance < distance) {
634
+ distance = actualDistance;
635
+ hitObstacle = true;
636
+ }
637
+ }
638
+ }
639
+ }
640
+
641
+ // Check canvas boundaries
642
+ const boundaryDistance = this.checkBoundaryDistance(angle);
643
+ if (boundaryDistance < distance) {
644
+ distance = boundaryDistance;
645
+ }
646
+
647
+ this.sensors.push({
648
+ angle: angle,
649
+ distance: distance,
650
+ x: this.x + Math.cos(angle) * distance,
651
+ y: this.y + Math.sin(angle) * distance,
652
+ hitObstacle: hitObstacle
653
+ });
654
+ }
655
+ }
656
+
657
+ checkBoundaryDistance(angle) {
658
+ const canvasWidth = canvas.width / devicePixelRatio;
659
+ const canvasHeight = canvas.height / devicePixelRatio;
660
+
661
+ const cos = Math.cos(angle);
662
+ const sin = Math.sin(angle);
663
+
664
+ let distance = this.sensorRange;
665
+
666
+ if (cos > 0) {
667
+ distance = Math.min(distance, (canvasWidth - this.x) / cos);
668
+ } else if (cos < 0) {
669
+ distance = Math.min(distance, -this.x / cos);
670
+ }
671
+
672
+ if (sin > 0) {
673
+ distance = Math.min(distance, (canvasHeight - this.y) / sin);
674
+ } else if (sin < 0) {
675
+ distance = Math.min(distance, -this.y / sin);
676
+ }
677
+
678
+ return Math.max(0, distance - 10); // Margin from boundaries
679
+ }
680
+ }
681
+ </script>