docto41 commited on
Commit
085a81a
·
verified ·
1 Parent(s): 385a2fa

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +679 -101
  2. prompts.txt +2 -1
index.html CHANGED
@@ -42,11 +42,12 @@
42
  position: absolute;
43
  bottom: 0;
44
  width: 100%;
45
- height: 40%;
46
  background-size: cover;
47
  background-position: center;
48
  z-index: 5;
49
  pointer-events: none;
 
50
  }
51
 
52
  .dashboard {
@@ -55,12 +56,15 @@
55
  left: 0;
56
  width: 100%;
57
  height: 30%;
58
- background: rgba(0, 0, 0, 0.5);
59
- backdrop-filter: blur(5px);
60
  z-index: 10;
61
  display: flex;
62
  flex-direction: column;
63
  padding: 15px;
 
 
 
64
  }
65
 
66
  .speedometer-container {
@@ -72,8 +76,8 @@
72
 
73
  .speedometer {
74
  position: relative;
75
- width: 120px;
76
- height: 120px;
77
  }
78
 
79
  .speed-value {
@@ -81,29 +85,33 @@
81
  top: 50%;
82
  left: 50%;
83
  transform: translate(-50%, -50%);
84
- font-size: 24px;
85
  font-weight: bold;
 
86
  }
87
 
88
  .needle {
89
  position: absolute;
90
  bottom: 50%;
91
  left: 50%;
92
- width: 3px;
93
- height: 50px;
94
  background: red;
95
  transform-origin: 50% 100%;
96
  transform: translateX(-50%) rotate(-90deg);
97
  transition: transform 0.1s;
 
 
98
  }
99
 
100
  .rpm-meter {
101
  width: 100%;
102
- height: 20px;
103
  background: rgba(255, 255, 255, 0.1);
104
- border-radius: 10px;
105
  overflow: hidden;
106
  margin: 10px 0;
 
107
  }
108
 
109
  .rpm-fill {
@@ -111,6 +119,7 @@
111
  background: linear-gradient(to right, #3b82f6, #ef4444);
112
  width: 0%;
113
  transition: width 0.1s;
 
114
  }
115
 
116
  .controls {
@@ -124,17 +133,23 @@
124
  }
125
 
126
  .control-btn {
127
- width: 60px;
128
- height: 60px;
129
  background: rgba(0, 0, 0, 0.7);
130
  border-radius: 50%;
131
  display: flex;
132
  align-items: center;
133
  justify-content: center;
134
- font-size: 24px;
135
  cursor: pointer;
136
  user-select: none;
137
  backdrop-filter: blur(5px);
 
 
 
 
 
 
138
  }
139
 
140
  .vehicle-selector {
@@ -142,38 +157,43 @@
142
  top: 20px;
143
  left: 20px;
144
  z-index: 20;
145
- background: rgba(0, 0, 0, 0.7);
146
  border-radius: 15px;
147
  padding: 15px;
148
- backdrop-filter: blur(5px);
149
  max-height: 80vh;
150
  overflow-y: auto;
 
151
  }
152
 
153
  .vehicle-card {
154
- width: 120px;
155
  padding: 10px;
156
- margin: 5px;
157
  background: rgba(255, 255, 255, 0.1);
158
- border-radius: 10px;
159
  cursor: pointer;
160
  transition: all 0.3s;
 
161
  }
162
 
163
  .vehicle-card:hover {
164
  background: rgba(255, 255, 255, 0.2);
165
  transform: scale(1.05);
 
166
  }
167
 
168
  .vehicle-card.selected {
169
  background: #3b82f6;
 
170
  }
171
 
172
  .vehicle-img {
173
  width: 100%;
174
- height: 60px;
175
  object-fit: contain;
176
- margin-bottom: 5px;
 
177
  }
178
 
179
  .environment-selector {
@@ -181,27 +201,31 @@
181
  top: 20px;
182
  right: 20px;
183
  z-index: 20;
184
- background: rgba(0, 0, 0, 0.7);
185
  border-radius: 15px;
186
  padding: 15px;
187
- backdrop-filter: blur(5px);
 
188
  }
189
 
190
  .environment-btn {
191
- padding: 8px 12px;
192
- margin: 5px;
193
  background: rgba(255, 255, 255, 0.1);
194
- border-radius: 8px;
195
  cursor: pointer;
196
  transition: all 0.3s;
 
197
  }
198
 
199
  .environment-btn:hover {
200
  background: rgba(255, 255, 255, 0.2);
 
201
  }
202
 
203
  .environment-btn.selected {
204
  background: #3b82f6;
 
205
  }
206
 
207
  .loading-screen {
@@ -216,79 +240,250 @@
216
  align-items: center;
217
  justify-content: center;
218
  z-index: 100;
 
219
  }
220
 
221
  .progress-bar {
222
- width: 300px;
223
- height: 10px;
224
  background: rgba(255, 255, 255, 0.2);
225
- border-radius: 5px;
226
- margin-top: 20px;
227
  overflow: hidden;
 
228
  }
229
 
230
  .progress {
231
  height: 100%;
232
- background: #3b82f6;
233
  width: 0%;
234
  transition: width 0.3s;
 
235
  }
236
 
237
  .steering-wheel {
238
  position: absolute;
239
- bottom: 100px;
240
  left: 50%;
241
  transform: translateX(-50%);
242
- width: 150px;
243
- height: 150px;
244
  background-image: url('https://www.freeiconspng.com/uploads/steering-wheel-png-33.png');
245
  background-size: contain;
246
  background-repeat: no-repeat;
247
  z-index: 10;
248
  transition: transform 0.3s;
 
249
  }
250
 
251
  .dashboard-indicators {
252
  display: flex;
253
  justify-content: space-between;
254
- margin-top: 10px;
255
  }
256
 
257
  .indicator {
258
  display: flex;
259
  flex-direction: column;
260
  align-items: center;
261
- padding: 5px 10px;
262
- background: rgba(0, 0, 0, 0.3);
263
- border-radius: 5px;
 
 
264
  }
265
 
266
  .indicator-value {
267
- font-size: 18px;
268
  font-weight: bold;
 
269
  }
270
 
271
  .indicator-label {
272
- font-size: 12px;
273
  color: #aaa;
274
  }
275
 
276
  .gear-display {
277
- font-size: 24px;
278
  font-weight: bold;
279
  text-align: center;
280
  margin: 10px 0;
281
- background: rgba(0, 0, 0, 0.5);
282
- border-radius: 5px;
283
- padding: 5px 15px;
284
  display: inline-block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
286
  </style>
287
  </head>
288
  <body>
289
  <div class="loading-screen">
290
- <h1 class="text-3xl font-bold mb-4">CHARGEMENT DU SIMULATEUR</h1>
291
- <p class="text-gray-400">Initialisation des modules physiques...</p>
292
  <div class="progress-bar">
293
  <div class="progress" id="loading-progress"></div>
294
  </div>
@@ -298,20 +493,62 @@
298
  <!-- Vue de la route avec images réelles -->
299
  <div id="road-view"></div>
300
 
 
 
 
 
 
 
 
 
301
  <!-- Intérieur de voiture réaliste -->
302
  <div class="car-interior" id="car-interior"></div>
303
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
  <!-- Volant animé -->
305
  <div class="steering-wheel" id="steering-wheel"></div>
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  <!-- Tableau de bord complet -->
308
  <div class="dashboard">
 
 
 
 
 
309
  <div class="speedometer-container">
310
  <div class="speedometer">
311
- <svg viewBox="0 0 100 100" width="120" height="120">
312
  <circle cx="50" cy="50" r="45" fill="none" stroke="#333" stroke-width="8"/>
313
  <circle cx="50" cy="50" r="45" fill="none" stroke="#3b82f6" stroke-width="8" stroke-dasharray="283" stroke-dashoffset="141.5" transform="rotate(-90 50 50)"/>
314
  <text x="50" y="20" text-anchor="middle" fill="white" font-size="10">km/h</text>
 
 
315
  </svg>
316
  <div class="speed-value" id="speed-value">0</div>
317
  <div class="needle" id="needle"></div>
@@ -322,6 +559,7 @@
322
  <div class="rpm-meter">
323
  <div class="rpm-fill" id="rpm-fill"></div>
324
  </div>
 
325
  </div>
326
  </div>
327
 
@@ -339,9 +577,13 @@
339
  <div class="indicator-label">Temps</div>
340
  </div>
341
  <div class="indicator">
342
- <div class="indicator-value"><i class="fas fa-temperature-high" id="temp-icon"></i></div>
343
  <div class="indicator-label">Moteur</div>
344
  </div>
 
 
 
 
345
  </div>
346
  </div>
347
 
@@ -356,57 +598,124 @@
356
  <div class="control-btn" id="horn-btn">
357
  <i class="fas fa-bullhorn"></i>
358
  </div>
 
 
 
359
  </div>
360
 
361
  <!-- Sélection du véhicule -->
362
  <div class="vehicle-selector">
363
- <h2 class="text-xl font-bold mb-4">Sélection du véhicule</h2>
364
 
365
- <h3 class="font-semibold mb-2 text-blue-400">Véhicules Réels</h3>
366
  <div class="flex flex-wrap">
367
- <div class="vehicle-card" data-vehicle="peugeot-308">
368
  <img src="https://www.largus.fr/images/images/peugeot-308-2021-1.jpg" class="vehicle-img">
369
- <div class="text-center text-sm">Peugeot 308</div>
370
  </div>
371
  <div class="vehicle-card" data-vehicle="bmw-serie3">
372
  <img src="https://www.bmw.fr/content/dam/bmw/marketFR/bmw_fr/all-models/3-series/sedan/2021/overview/bmw-3-series-sedan-sp-desktop.jpg" class="vehicle-img">
373
- <div class="text-center text-sm">BMW Série 3</div>
374
  </div>
375
  <div class="vehicle-card" data-vehicle="audi-a4">
376
  <img src="https://www.audi.fr/content/dam/nemo/models/a4/a4-sedan/my-2022/1920x1080-mtc-xxl/1920x1080-a4-sedan-2022_2.jpg" class="vehicle-img">
377
- <div class="text-center text-sm">Audi A4</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  </div>
379
  </div>
380
 
381
- <button id="start-btn" class="w-full mt-4 bg-green-600 hover:bg-green-700 py-2 rounded font-bold">
382
- <i class="fas fa-play mr-2"></i> Démarrer
383
  </button>
384
  </div>
385
 
386
  <!-- Sélection de l'environnement -->
387
  <div class="environment-selector">
388
- <h2 class="text-xl font-bold mb-4">Environnement</h2>
389
- <div class="environment-btn selected" data-env="paris">Paris</div>
390
- <div class="environment-btn" data-env="autoroute">Autoroute A6</div>
391
- <div class="environment-btn" data-env="provence">Provence</div>
392
- <div class="environment-btn" data-env="alpes">Alpes</div>
 
 
 
 
 
 
 
 
393
  </div>
394
  </div>
395
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  <script>
397
  // Simulation des données de chargement
398
  setTimeout(() => {
399
  let progress = 0;
 
 
 
 
 
 
 
 
 
 
400
  const interval = setInterval(() => {
401
- progress += Math.random() * 10;
402
  if (progress >= 100) {
403
  progress = 100;
404
  clearInterval(interval);
405
  document.querySelector('.loading-screen').style.opacity = '0';
406
  setTimeout(() => {
407
  document.querySelector('.loading-screen').style.display = 'none';
408
- }, 300);
 
 
 
 
 
 
 
 
 
 
409
  }
 
410
  document.getElementById('loading-progress').style.width = progress + '%';
411
  }, 100);
412
  }, 500);
@@ -416,7 +725,8 @@
416
  physics: {
417
  gravity: 9.81,
418
  friction: 0.98,
419
- drag: 0.99
 
420
  },
421
  vehicles: {
422
  'peugeot-308': {
@@ -424,21 +734,36 @@
424
  acceleration: 0.05,
425
  deceleration: 0.1,
426
  mass: 1300,
427
- interiorImg: 'https://www.cars-data.com/pictures/peugeot/peugeot-308_3955_1.jpg'
 
 
428
  },
429
  'bmw-serie3': {
430
  maxSpeed: 250,
431
  acceleration: 0.07,
432
  deceleration: 0.12,
433
  mass: 1450,
434
- interiorImg: 'https://www.bmw.fr/content/dam/bmw/marketFR/bmw_fr/all-models/3-series/sedan/2021/interior-and-exterior/bmw-3-series-sedan-interior-design-sp-desktop.jpg'
 
 
435
  },
436
  'audi-a4': {
437
  maxSpeed: 240,
438
  acceleration: 0.06,
439
  deceleration: 0.11,
440
  mass: 1400,
441
- interiorImg: 'https://www.audi.fr/content/dam/nemo/models/a4/a4-sedan/my-2022/1920x1080-mtc-xxl/1920x1080-a4-sedan-2022_2.jpg'
 
 
 
 
 
 
 
 
 
 
 
442
  }
443
  },
444
  environments: {
@@ -448,6 +773,10 @@
448
  'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Paris_Rue_de_Rivoli.jpg/1200px-Paris_Rue_de_Rivoli.jpg',
449
  'https://cdn.getyourguide.com/img/location/5c9f1b2e82550.jpeg/88.jpg',
450
  'https://www.sortiraparis.com/images/80/83517/577341-visuel-paris-rue-de-sevigne.jpg'
 
 
 
 
451
  ]
452
  },
453
  'autoroute': {
@@ -455,6 +784,9 @@
455
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg',
456
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg',
457
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg'
 
 
 
458
  ]
459
  },
460
  'provence': {
@@ -462,6 +794,10 @@
462
  'https://www.provenceweb.fr/f/albums/route-provence.jpg',
463
  'https://www.provenceweb.fr/f/albums/route-provence-2.jpg',
464
  'https://www.provenceweb.fr/f/albums/route-provence-3.jpg'
 
 
 
 
465
  ]
466
  },
467
  'alpes': {
@@ -469,33 +805,61 @@
469
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes.jpg',
470
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes-2.jpg',
471
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes-3.jpg'
 
 
 
 
472
  ]
473
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
474
  }
475
  };
476
 
477
  // État du jeu
478
  const gameState = {
479
  active: false,
480
- vehicle: null,
481
  environment: 'paris',
 
482
  speed: 0,
483
  rpm: 0,
484
  gear: 'N',
485
  steering: 0,
486
  acceleration: 0,
487
  braking: 0,
 
488
  handbrake: false,
489
  lights: false,
490
  horn: false,
 
491
  fuel: 100,
492
  distance: 0,
 
493
  startTime: null,
494
  lastUpdate: null,
495
  keys: {},
496
  currentRoadIndex: 0,
497
  engineTemp: 80,
498
- vibrationIntensity: 0
 
 
 
499
  };
500
 
501
  // Fonction pour changer l'image de la route
@@ -506,25 +870,86 @@
506
  const roadImages = env.roadImages;
507
 
508
  // Changer d'image selon la vitesse
509
- if (Math.abs(gameState.speed) > 50) {
510
- gameState.currentRoadIndex = (gameState.currentRoadIndex + 1) % roadImages.length;
511
- document.getElementById('road-view').style.backgroundImage = `url(${roadImages[gameState.currentRoadIndex]})`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  }
513
  }
514
 
515
  // Animation du jeu
516
  function animate() {
517
  if (gameState.active) {
 
518
  updatePhysics();
519
  updateVehicle();
520
  updateRoadView();
521
  updateUI();
522
  updateVibration();
 
 
523
  }
524
 
525
  requestAnimationFrame(animate);
526
  }
527
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
528
  function updatePhysics() {
529
  const now = new Date();
530
  const deltaTime = (now - gameState.lastUpdate) / 1000; // en secondes
@@ -532,30 +957,54 @@
532
 
533
  if (deltaTime > 0.1) return; // Éviter les sauts de temps trop grands
534
 
 
 
 
 
535
  // Mise à jour de la position et de la vitesse
536
  if (gameState.gear !== 'N') {
537
  // Accélération
538
  if (gameState.acceleration > 0) {
539
  if (gameState.gear === 'R') {
540
- gameState.speed -= config.vehicles[gameState.vehicle].acceleration * deltaTime * 0.5;
541
  } else {
542
- gameState.speed += config.vehicles[gameState.vehicle].acceleration * deltaTime;
543
  }
544
  }
545
 
546
  // Freinage
547
  if (gameState.braking > 0) {
548
- gameState.speed -= config.vehicles[gameState.vehicle].deceleration * deltaTime;
549
  }
550
 
551
  // Frein à main
552
  if (gameState.handbrake) {
553
- gameState.speed *= 0.95;
 
 
 
 
 
 
554
  }
555
 
556
  // Décélération naturelle
557
  if (gameState.acceleration === 0 && gameState.braking === 0 && !gameState.handbrake) {
558
- gameState.speed *= config.physics.friction;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
559
  }
560
 
561
  // Limite de vitesse selon la marche
@@ -580,29 +1029,48 @@
580
  gameState.engineTemp += (gameState.rpm - 2) * deltaTime * 2;
581
  gameState.engineTemp = Math.max(60, Math.min(gameState.engineTemp, 120));
582
 
 
 
 
 
 
 
583
  // Consommation de carburant
584
  gameState.fuel -= (gameState.rpm / 100) * deltaTime;
585
  gameState.fuel = Math.max(0, gameState.fuel);
586
 
587
  if (gameState.fuel <= 0) {
588
  gameState.speed *= 0.98; // Ralentir si plus de carburant
 
589
  }
590
  } else { // Point mort
591
  gameState.rpm = 0.5;
592
- gameState.speed *= 0.95; // Ralentir plus vite en point mort
593
  gameState.engineTemp = Math.max(60, gameState.engineTemp - deltaTime * 5);
594
  }
595
 
596
  // Mise à jour de la distance parcourue
597
- gameState.distance += (Math.abs(gameState.speed) * deltaTime) / 3600; // en km
 
 
598
 
599
  // Intensité des vibrations
600
- gameState.vibrationIntensity = Math.min(Math.abs(gameState.speed) / 100, 0.1);
 
 
 
 
 
601
  }
602
 
603
  function updateVehicle() {
604
  // Rotation du volant
605
  document.getElementById('steering-wheel').style.transform = `translateX(-50%) rotate(${gameState.steering * 180}deg)`;
 
 
 
 
 
606
  }
607
 
608
  function updateVibration() {
@@ -610,11 +1078,61 @@
610
  if (gameState.vibrationIntensity > 0.01) {
611
  const shakeX = Math.sin(Date.now() * 0.01) * gameState.vibrationIntensity;
612
  const shakeY = Math.sin(Date.now() * 0.007) * gameState.vibrationIntensity * 0.5;
613
- document.getElementById('road-view').style.transform = `translate(${shakeX}px, ${shakeY}px)`;
614
  document.getElementById('car-interior').style.transform = `translate(${shakeX * 0.5}px, ${shakeY * 0.5}px)`;
 
 
 
 
615
  } else {
616
- document.getElementById('road-view').style.transform = 'translate(0, 0)';
617
  document.getElementById('car-interior').style.transform = 'translate(0, 0)';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618
  }
619
  }
620
 
@@ -635,6 +1153,7 @@
635
 
636
  // Distance
637
  document.getElementById('distance-display').textContent = gameState.distance.toFixed(1);
 
638
 
639
  // Temps
640
  if (gameState.startTime) {
@@ -645,13 +1164,15 @@
645
  }
646
 
647
  // Température moteur
648
- const tempIcon = document.getElementById('temp-icon');
 
 
649
  if (gameState.engineTemp > 100) {
650
- tempIcon.style.color = '#ef4444';
651
  } else if (gameState.engineTemp > 90) {
652
- tempIcon.style.color = '#f59e0b';
653
  } else {
654
- tempIcon.style.color = '#3b82f6';
655
  }
656
  }
657
 
@@ -664,18 +1185,34 @@
664
 
665
  // Mettre à jour l'intérieur du véhicule
666
  document.getElementById('car-interior').style.backgroundImage = `url(${config.vehicles[gameState.vehicle].interiorImg})`;
 
 
 
 
 
 
 
 
 
667
  });
668
  });
669
 
670
  document.querySelectorAll('.environment-btn').forEach(btn => {
671
  btn.addEventListener('click', () => {
672
- document.querySelectorAll('.environment-btn').forEach(b => b.classList.remove('selected'));
673
- btn.classList.add('selected');
674
- gameState.environment = btn.dataset.env;
675
-
676
- // Mettre à jour la vue de la route
677
- const env = config.environments[gameState.environment];
678
- document.getElementById('road-view').style.backgroundImage = `url(${env.roadImages[0]})`;
 
 
 
 
 
 
 
679
  });
680
  });
681
 
@@ -688,6 +1225,7 @@
688
  gameState.active = true;
689
  gameState.startTime = new Date();
690
  gameState.lastUpdate = new Date();
 
691
  gameState.speed = 0;
692
  gameState.rpm = 0;
693
  gameState.gear = 'N';
@@ -695,13 +1233,24 @@
695
  gameState.distance = 0;
696
  gameState.currentRoadIndex = 0;
697
  gameState.engineTemp = 80;
 
 
698
 
699
  // Masquer le sélecteur de véhicule
700
  document.querySelector('.vehicle-selector').style.display = 'none';
 
701
 
702
  // Initialiser la vue de la route
703
  const env = config.environments[gameState.environment];
704
  document.getElementById('road-view').style.backgroundImage = `url(${env.roadImages[0]})`;
 
 
 
 
 
 
 
 
705
  });
706
 
707
  document.getElementById('handbrake-btn').addEventListener('click', () => {
@@ -712,17 +1261,19 @@
712
  document.getElementById('lights-btn').addEventListener('click', () => {
713
  gameState.lights = !gameState.lights;
714
  document.getElementById('lights-btn').classList.toggle('bg-yellow-500');
715
- // Ici vous pourriez changer la luminosité de la vue
716
  });
717
 
718
  document.getElementById('horn-btn').addEventListener('click', () => {
719
  gameState.horn = true;
720
  document.getElementById('horn-btn').classList.add('bg-yellow-500');
721
- // Jouer un son de klaxon
722
  setTimeout(() => {
723
- gameState.horn = false;
724
  document.getElementById('horn-btn').classList.remove('bg-yellow-500');
725
- }, 1000);
 
 
 
 
 
726
  });
727
 
728
  // Contrôles clavier
@@ -743,6 +1294,9 @@
743
  // Freinage
744
  gameState.braking = gameState.keys['s'] || gameState.keys['arrowdown'] ? 1 : 0;
745
 
 
 
 
746
  // Direction
747
  if (gameState.keys['a'] || gameState.keys['arrowleft']) {
748
  gameState.steering = -1;
@@ -784,9 +1338,6 @@
784
  if (gameState.keys['h']) {
785
  gameState.horn = true;
786
  document.getElementById('horn-btn').classList.add('bg-yellow-500');
787
- } else {
788
- gameState.horn = false;
789
- document.getElementById('horn-btn').classList.remove('bg-yellow-500');
790
  }
791
 
792
  // Phares
@@ -794,11 +1345,29 @@
794
  gameState.lights = !gameState.lights;
795
  document.getElementById('lights-btn').classList.toggle('bg-yellow-500');
796
  }
 
 
 
 
 
 
 
 
 
797
  }
798
 
799
  function changeGear(newGear) {
800
- gameState.gear = newGear;
801
- document.getElementById('gear-display').textContent = newGear;
 
 
 
 
 
 
 
 
 
802
  }
803
 
804
  // Initialisation
@@ -806,6 +1375,15 @@
806
  animate();
807
  document.querySelector('.vehicle-card[data-vehicle="peugeot-308"]').click();
808
  document.querySelector('.environment-btn[data-env="paris"]').click();
 
 
 
 
 
 
 
 
 
809
  }, 1500);
810
  </script>
811
  <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=docto41/ultimate-driving-simulator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
 
42
  position: absolute;
43
  bottom: 0;
44
  width: 100%;
45
+ height: 45%;
46
  background-size: cover;
47
  background-position: center;
48
  z-index: 5;
49
  pointer-events: none;
50
+ border-top: 2px solid rgba(255,255,255,0.1);
51
  }
52
 
53
  .dashboard {
 
56
  left: 0;
57
  width: 100%;
58
  height: 30%;
59
+ background: rgba(0, 0, 0, 0.7);
60
+ backdrop-filter: blur(8px);
61
  z-index: 10;
62
  display: flex;
63
  flex-direction: column;
64
  padding: 15px;
65
+ border-top-left-radius: 20px;
66
+ border-top-right-radius: 20px;
67
+ box-shadow: 0 -5px 15px rgba(0,0,0,0.5);
68
  }
69
 
70
  .speedometer-container {
 
76
 
77
  .speedometer {
78
  position: relative;
79
+ width: 140px;
80
+ height: 140px;
81
  }
82
 
83
  .speed-value {
 
85
  top: 50%;
86
  left: 50%;
87
  transform: translate(-50%, -50%);
88
+ font-size: 28px;
89
  font-weight: bold;
90
+ text-shadow: 0 0 10px rgba(59, 130, 246, 0.7);
91
  }
92
 
93
  .needle {
94
  position: absolute;
95
  bottom: 50%;
96
  left: 50%;
97
+ width: 4px;
98
+ height: 60px;
99
  background: red;
100
  transform-origin: 50% 100%;
101
  transform: translateX(-50%) rotate(-90deg);
102
  transition: transform 0.1s;
103
+ border-radius: 2px;
104
+ box-shadow: 0 0 5px rgba(255,0,0,0.7);
105
  }
106
 
107
  .rpm-meter {
108
  width: 100%;
109
+ height: 25px;
110
  background: rgba(255, 255, 255, 0.1);
111
+ border-radius: 12px;
112
  overflow: hidden;
113
  margin: 10px 0;
114
+ box-shadow: inset 0 0 10px rgba(0,0,0,0.5);
115
  }
116
 
117
  .rpm-fill {
 
119
  background: linear-gradient(to right, #3b82f6, #ef4444);
120
  width: 0%;
121
  transition: width 0.1s;
122
+ border-radius: 12px;
123
  }
124
 
125
  .controls {
 
133
  }
134
 
135
  .control-btn {
136
+ width: 70px;
137
+ height: 70px;
138
  background: rgba(0, 0, 0, 0.7);
139
  border-radius: 50%;
140
  display: flex;
141
  align-items: center;
142
  justify-content: center;
143
+ font-size: 28px;
144
  cursor: pointer;
145
  user-select: none;
146
  backdrop-filter: blur(5px);
147
+ box-shadow: 0 5px 15px rgba(0,0,0,0.3);
148
+ transition: all 0.2s;
149
+ }
150
+
151
+ .control-btn:active {
152
+ transform: scale(0.95);
153
  }
154
 
155
  .vehicle-selector {
 
157
  top: 20px;
158
  left: 20px;
159
  z-index: 20;
160
+ background: rgba(0, 0, 0, 0.8);
161
  border-radius: 15px;
162
  padding: 15px;
163
+ backdrop-filter: blur(10px);
164
  max-height: 80vh;
165
  overflow-y: auto;
166
+ box-shadow: 0 5px 15px rgba(0,0,0,0.5);
167
  }
168
 
169
  .vehicle-card {
170
+ width: 140px;
171
  padding: 10px;
172
+ margin: 8px;
173
  background: rgba(255, 255, 255, 0.1);
174
+ border-radius: 12px;
175
  cursor: pointer;
176
  transition: all 0.3s;
177
+ border: 1px solid rgba(255,255,255,0.1);
178
  }
179
 
180
  .vehicle-card:hover {
181
  background: rgba(255, 255, 255, 0.2);
182
  transform: scale(1.05);
183
+ border-color: rgba(255,255,255,0.3);
184
  }
185
 
186
  .vehicle-card.selected {
187
  background: #3b82f6;
188
+ box-shadow: 0 0 15px rgba(59, 130, 246, 0.7);
189
  }
190
 
191
  .vehicle-img {
192
  width: 100%;
193
+ height: 80px;
194
  object-fit: contain;
195
+ margin-bottom: 8px;
196
+ border-radius: 8px;
197
  }
198
 
199
  .environment-selector {
 
201
  top: 20px;
202
  right: 20px;
203
  z-index: 20;
204
+ background: rgba(0, 0, 0, 0.8);
205
  border-radius: 15px;
206
  padding: 15px;
207
+ backdrop-filter: blur(10px);
208
+ box-shadow: 0 5px 15px rgba(0,0,0,0.5);
209
  }
210
 
211
  .environment-btn {
212
+ padding: 10px 15px;
213
+ margin: 6px;
214
  background: rgba(255, 255, 255, 0.1);
215
+ border-radius: 10px;
216
  cursor: pointer;
217
  transition: all 0.3s;
218
+ border: 1px solid rgba(255,255,255,0.1);
219
  }
220
 
221
  .environment-btn:hover {
222
  background: rgba(255, 255, 255, 0.2);
223
+ border-color: rgba(255,255,255,0.3);
224
  }
225
 
226
  .environment-btn.selected {
227
  background: #3b82f6;
228
+ box-shadow: 0 0 10px rgba(59, 130, 246, 0.7);
229
  }
230
 
231
  .loading-screen {
 
240
  align-items: center;
241
  justify-content: center;
242
  z-index: 100;
243
+ transition: opacity 0.5s;
244
  }
245
 
246
  .progress-bar {
247
+ width: 350px;
248
+ height: 12px;
249
  background: rgba(255, 255, 255, 0.2);
250
+ border-radius: 6px;
251
+ margin-top: 25px;
252
  overflow: hidden;
253
+ box-shadow: inset 0 0 10px rgba(0,0,0,0.5);
254
  }
255
 
256
  .progress {
257
  height: 100%;
258
+ background: linear-gradient(to right, #3b82f6, #6366f1);
259
  width: 0%;
260
  transition: width 0.3s;
261
+ border-radius: 6px;
262
  }
263
 
264
  .steering-wheel {
265
  position: absolute;
266
+ bottom: 120px;
267
  left: 50%;
268
  transform: translateX(-50%);
269
+ width: 180px;
270
+ height: 180px;
271
  background-image: url('https://www.freeiconspng.com/uploads/steering-wheel-png-33.png');
272
  background-size: contain;
273
  background-repeat: no-repeat;
274
  z-index: 10;
275
  transition: transform 0.3s;
276
+ filter: drop-shadow(0 0 10px rgba(0,0,0,0.7));
277
  }
278
 
279
  .dashboard-indicators {
280
  display: flex;
281
  justify-content: space-between;
282
+ margin-top: 15px;
283
  }
284
 
285
  .indicator {
286
  display: flex;
287
  flex-direction: column;
288
  align-items: center;
289
+ padding: 8px 12px;
290
+ background: rgba(0, 0, 0, 0.4);
291
+ border-radius: 8px;
292
+ min-width: 80px;
293
+ border: 1px solid rgba(255,255,255,0.1);
294
  }
295
 
296
  .indicator-value {
297
+ font-size: 20px;
298
  font-weight: bold;
299
+ margin-bottom: 3px;
300
  }
301
 
302
  .indicator-label {
303
+ font-size: 13px;
304
  color: #aaa;
305
  }
306
 
307
  .gear-display {
308
+ font-size: 28px;
309
  font-weight: bold;
310
  text-align: center;
311
  margin: 10px 0;
312
+ background: rgba(0, 0, 0, 0.6);
313
+ border-radius: 10px;
314
+ padding: 8px 20px;
315
  display: inline-block;
316
+ min-width: 60px;
317
+ border: 1px solid rgba(255,255,255,0.1);
318
+ box-shadow: 0 0 10px rgba(0,0,0,0.3);
319
+ }
320
+
321
+ .road-effects {
322
+ position: absolute;
323
+ top: 0;
324
+ left: 0;
325
+ width: 100%;
326
+ height: 100%;
327
+ z-index: 2;
328
+ pointer-events: none;
329
+ }
330
+
331
+ .speed-lines {
332
+ position: absolute;
333
+ top: 0;
334
+ left: 0;
335
+ width: 100%;
336
+ height: 100%;
337
+ background: linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.03) 50%, rgba(255,255,255,0) 100%);
338
+ background-size: 100% 10px;
339
+ opacity: 0;
340
+ }
341
+
342
+ .headlights {
343
+ position: absolute;
344
+ bottom: 0;
345
+ left: 0;
346
+ width: 100%;
347
+ height: 60%;
348
+ background: radial-gradient(ellipse at center, rgba(255,240,200,0.3) 0%, rgba(255,240,200,0) 70%);
349
+ opacity: 0;
350
+ z-index: 3;
351
+ }
352
+
353
+ .windshield-drops {
354
+ position: absolute;
355
+ top: 0;
356
+ left: 0;
357
+ width: 100%;
358
+ height: 100%;
359
+ background-image: url('https://www.transparenttextures.com/patterns/water-pattern.png');
360
+ opacity: 0;
361
+ z-index: 4;
362
+ }
363
+
364
+ .mirror-left, .mirror-right {
365
+ position: absolute;
366
+ width: 15%;
367
+ height: 20%;
368
+ background: rgba(0,0,0,0.5);
369
+ border: 1px solid rgba(255,255,255,0.2);
370
+ z-index: 6;
371
+ overflow: hidden;
372
+ }
373
+
374
+ .mirror-left {
375
+ top: 15%;
376
+ left: 2%;
377
+ border-radius: 5px 0 0 5px;
378
+ }
379
+
380
+ .mirror-right {
381
+ top: 15%;
382
+ right: 2%;
383
+ border-radius: 0 5px 5px 0;
384
+ }
385
+
386
+ .mirror-content {
387
+ width: 100%;
388
+ height: 100%;
389
+ background-size: cover;
390
+ transform: scaleX(-1);
391
+ filter: brightness(0.7);
392
+ }
393
+
394
+ .pedals {
395
+ position: absolute;
396
+ bottom: 30px;
397
+ left: 50%;
398
+ transform: translateX(-50%);
399
+ display: flex;
400
+ gap: 30px;
401
+ z-index: 7;
402
+ }
403
+
404
+ .pedal {
405
+ width: 50px;
406
+ height: 80px;
407
+ background: rgba(0,0,0,0.7);
408
+ border-radius: 5px;
409
+ display: flex;
410
+ align-items: flex-end;
411
+ justify-content: center;
412
+ padding-bottom: 10px;
413
+ font-size: 12px;
414
+ color: #aaa;
415
+ border: 1px solid rgba(255,255,255,0.1);
416
+ box-shadow: 0 5px 10px rgba(0,0,0,0.3);
417
+ }
418
+
419
+ .pedal.active {
420
+ background: rgba(255,0,0,0.5);
421
+ color: white;
422
+ }
423
+
424
+ .rear-view-mirror {
425
+ position: absolute;
426
+ top: 10%;
427
+ left: 50%;
428
+ transform: translateX(-50%);
429
+ width: 20%;
430
+ height: 15%;
431
+ background: rgba(0,0,0,0.5);
432
+ border: 1px solid rgba(255,255,255,0.2);
433
+ z-index: 6;
434
+ border-radius: 5px;
435
+ overflow: hidden;
436
+ }
437
+
438
+ .mirror-label {
439
+ position: absolute;
440
+ bottom: 5px;
441
+ left: 5px;
442
+ font-size: 10px;
443
+ color: rgba(255,255,255,0.5);
444
+ }
445
+
446
+ .time-weather {
447
+ position: absolute;
448
+ top: 20px;
449
+ left: 50%;
450
+ transform: translateX(-50%);
451
+ background: rgba(0,0,0,0.7);
452
+ padding: 8px 15px;
453
+ border-radius: 20px;
454
+ display: flex;
455
+ align-items: center;
456
+ gap: 10px;
457
+ z-index: 20;
458
+ backdrop-filter: blur(5px);
459
+ box-shadow: 0 5px 15px rgba(0,0,0,0.3);
460
+ }
461
+
462
+ .weather-icon {
463
+ font-size: 20px;
464
+ }
465
+
466
+ .time-display {
467
+ font-weight: bold;
468
+ }
469
+
470
+ .damage-effects {
471
+ position: absolute;
472
+ top: 0;
473
+ left: 0;
474
+ width: 100%;
475
+ height: 100%;
476
+ background: rgba(255,0,0,0);
477
+ z-index: 8;
478
+ pointer-events: none;
479
+ transition: background 0.3s;
480
  }
481
  </style>
482
  </head>
483
  <body>
484
  <div class="loading-screen">
485
+ <h1 class="text-4xl font-bold mb-6">SIMULATEUR DE CONDUITE RÉALISTE</h1>
486
+ <p class="text-gray-400 text-lg">Chargement des modules physiques...</p>
487
  <div class="progress-bar">
488
  <div class="progress" id="loading-progress"></div>
489
  </div>
 
493
  <!-- Vue de la route avec images réelles -->
494
  <div id="road-view"></div>
495
 
496
+ <!-- Effets visuels -->
497
+ <div class="road-effects">
498
+ <div class="speed-lines" id="speed-lines"></div>
499
+ <div class="headlights" id="headlights"></div>
500
+ <div class="windshield-drops" id="windshield-drops"></div>
501
+ <div class="damage-effects" id="damage-effects"></div>
502
+ </div>
503
+
504
  <!-- Intérieur de voiture réaliste -->
505
  <div class="car-interior" id="car-interior"></div>
506
 
507
+ <!-- Rétroviseurs -->
508
+ <div class="mirror-left">
509
+ <div class="mirror-content" id="left-mirror"></div>
510
+ <div class="mirror-label">Rétroviseur gauche</div>
511
+ </div>
512
+ <div class="mirror-right">
513
+ <div class="mirror-content" id="right-mirror"></div>
514
+ <div class="mirror-label">Rétroviseur droit</div>
515
+ </div>
516
+ <div class="rear-view-mirror">
517
+ <div class="mirror-content" id="rear-mirror"></div>
518
+ <div class="mirror-label">Rétroviseur central</div>
519
+ </div>
520
+
521
  <!-- Volant animé -->
522
  <div class="steering-wheel" id="steering-wheel"></div>
523
 
524
+ <!-- Pédales -->
525
+ <div class="pedals">
526
+ <div class="pedal" id="accelerator-pedal">
527
+ <div>Accélérateur</div>
528
+ </div>
529
+ <div class="pedal" id="brake-pedal">
530
+ <div>Frein</div>
531
+ </div>
532
+ <div class="pedal" id="clutch-pedal">
533
+ <div>Embrayage</div>
534
+ </div>
535
+ </div>
536
+
537
  <!-- Tableau de bord complet -->
538
  <div class="dashboard">
539
+ <div class="time-weather">
540
+ <div class="weather-icon" id="weather-icon"><i class="fas fa-sun"></i></div>
541
+ <div class="time-display" id="real-time">14:30</div>
542
+ </div>
543
+
544
  <div class="speedometer-container">
545
  <div class="speedometer">
546
+ <svg viewBox="0 0 100 100" width="140" height="140">
547
  <circle cx="50" cy="50" r="45" fill="none" stroke="#333" stroke-width="8"/>
548
  <circle cx="50" cy="50" r="45" fill="none" stroke="#3b82f6" stroke-width="8" stroke-dasharray="283" stroke-dashoffset="141.5" transform="rotate(-90 50 50)"/>
549
  <text x="50" y="20" text-anchor="middle" fill="white" font-size="10">km/h</text>
550
+ <text x="15" y="50" text-anchor="middle" fill="white" font-size="8">0</text>
551
+ <text x="85" y="50" text-anchor="middle" fill="white" font-size="8">260</text>
552
  </svg>
553
  <div class="speed-value" id="speed-value">0</div>
554
  <div class="needle" id="needle"></div>
 
559
  <div class="rpm-meter">
560
  <div class="rpm-fill" id="rpm-fill"></div>
561
  </div>
562
+ <div class="text-xs mt-1">RPM x1000</div>
563
  </div>
564
  </div>
565
 
 
577
  <div class="indicator-label">Temps</div>
578
  </div>
579
  <div class="indicator">
580
+ <div class="indicator-value"><i class="fas fa-temperature-high" id="temp-icon"></i> <span id="temp-value">85</span>°C</div>
581
  <div class="indicator-label">Moteur</div>
582
  </div>
583
+ <div class="indicator">
584
+ <div class="indicator-value" id="odometer">0</div>
585
+ <div class="indicator-label">Total km</div>
586
+ </div>
587
  </div>
588
  </div>
589
 
 
598
  <div class="control-btn" id="horn-btn">
599
  <i class="fas fa-bullhorn"></i>
600
  </div>
601
+ <div class="control-btn" id="wipers-btn">
602
+ <i class="fas fa-umbrella"></i>
603
+ </div>
604
  </div>
605
 
606
  <!-- Sélection du véhicule -->
607
  <div class="vehicle-selector">
608
+ <h2 class="text-2xl font-bold mb-4">Sélection du véhicule</h2>
609
 
610
+ <h3 class="font-semibold mb-3 text-blue-400">Véhicules Réels</h3>
611
  <div class="flex flex-wrap">
612
+ <div class="vehicle-card selected" data-vehicle="peugeot-308">
613
  <img src="https://www.largus.fr/images/images/peugeot-308-2021-1.jpg" class="vehicle-img">
614
+ <div class="text-center text-sm font-medium">Peugeot 308</div>
615
  </div>
616
  <div class="vehicle-card" data-vehicle="bmw-serie3">
617
  <img src="https://www.bmw.fr/content/dam/bmw/marketFR/bmw_fr/all-models/3-series/sedan/2021/overview/bmw-3-series-sedan-sp-desktop.jpg" class="vehicle-img">
618
+ <div class="text-center text-sm font-medium">BMW Série 3</div>
619
  </div>
620
  <div class="vehicle-card" data-vehicle="audi-a4">
621
  <img src="https://www.audi.fr/content/dam/nemo/models/a4/a4-sedan/my-2022/1920x1080-mtc-xxl/1920x1080-a4-sedan-2022_2.jpg" class="vehicle-img">
622
+ <div class="text-center text-sm font-medium">Audi A4</div>
623
+ </div>
624
+ <div class="vehicle-card" data-vehicle="tesla-model3">
625
+ <img src="https://www.tesla.com/sites/default/files/model3-new/social/model-3-hero-social.jpg" class="vehicle-img">
626
+ <div class="text-center text-sm font-medium">Tesla Model 3</div>
627
+ </div>
628
+ </div>
629
+
630
+ <div class="mt-6">
631
+ <h3 class="font-semibold mb-3 text-blue-400">Conditions météo</h3>
632
+ <div class="flex flex-wrap">
633
+ <div class="environment-btn" data-weather="sunny">
634
+ <i class="fas fa-sun mr-2"></i> Ensoleillé
635
+ </div>
636
+ <div class="environment-btn" data-weather="rainy">
637
+ <i class="fas fa-cloud-rain mr-2"></i> Pluvieux
638
+ </div>
639
+ <div class="environment-btn" data-weather="night">
640
+ <i class="fas fa-moon mr-2"></i> Nuit
641
+ </div>
642
  </div>
643
  </div>
644
 
645
+ <button id="start-btn" class="w-full mt-6 bg-green-600 hover:bg-green-700 py-3 rounded-lg font-bold text-lg transition-all">
646
+ <i class="fas fa-play mr-2"></i> Démarrer la Conduite
647
  </button>
648
  </div>
649
 
650
  <!-- Sélection de l'environnement -->
651
  <div class="environment-selector">
652
+ <h2 class="text-2xl font-bold mb-4">Environnement</h2>
653
+ <div class="environment-btn selected" data-env="paris">
654
+ <i class="fas fa-city mr-2"></i> Paris
655
+ </div>
656
+ <div class="environment-btn" data-env="autoroute">
657
+ <i class="fas fa-road mr-2"></i> Autoroute A6
658
+ </div>
659
+ <div class="environment-btn" data-env="provence">
660
+ <i class="fas fa-tree mr-2"></i> Provence
661
+ </div>
662
+ <div class="environment-btn" data-env="alpes">
663
+ <i class="fas fa-mountain mr-2"></i> Alpes
664
+ </div>
665
  </div>
666
  </div>
667
 
668
+ <audio id="engine-sound" loop>
669
+ <source src="https://www.soundjay.com/mechanical/sounds/car-engine-1.mp3" type="audio/mpeg">
670
+ </audio>
671
+
672
+ <audio id="horn-sound">
673
+ <source src="https://www.soundjay.com/mechanical/sounds/car-horn-1.mp3" type="audio/mpeg">
674
+ </audio>
675
+
676
+ <audio id="rain-sound" loop>
677
+ <source src="https://www.soundjay.com/nature/sounds/rain-01.mp3" type="audio/mpeg">
678
+ </audio>
679
+
680
+ <audio id="tire-sound" loop>
681
+ <source src="https://www.soundjay.com/mechanical/sounds/tire-skid-1.mp3" type="audio/mpeg">
682
+ </audio>
683
+
684
  <script>
685
  // Simulation des données de chargement
686
  setTimeout(() => {
687
  let progress = 0;
688
+ const loadingTexts = [
689
+ "Initialisation du moteur physique...",
690
+ "Chargement des textures HD...",
691
+ "Configuration des paramètres de conduite...",
692
+ "Optimisation des performances...",
693
+ "Préparation des effets sonores..."
694
+ ];
695
+ let currentText = 0;
696
+ const textElement = document.querySelector('.loading-screen p');
697
+
698
  const interval = setInterval(() => {
699
+ progress += Math.random() * 8;
700
  if (progress >= 100) {
701
  progress = 100;
702
  clearInterval(interval);
703
  document.querySelector('.loading-screen').style.opacity = '0';
704
  setTimeout(() => {
705
  document.querySelector('.loading-screen').style.display = 'none';
706
+ // Démarrer le son d'ambiance
707
+ document.getElementById('engine-sound').volume = 0.3;
708
+ document.getElementById('engine-sound').play();
709
+ }, 500);
710
+ }
711
+
712
+ if (progress > (currentText + 1) * 20) {
713
+ currentText++;
714
+ if (currentText < loadingTexts.length) {
715
+ textElement.textContent = loadingTexts[currentText];
716
+ }
717
  }
718
+
719
  document.getElementById('loading-progress').style.width = progress + '%';
720
  }, 100);
721
  }, 500);
 
725
  physics: {
726
  gravity: 9.81,
727
  friction: 0.98,
728
+ drag: 0.99,
729
+ tireGrip: 0.9
730
  },
731
  vehicles: {
732
  'peugeot-308': {
 
734
  acceleration: 0.05,
735
  deceleration: 0.1,
736
  mass: 1300,
737
+ interiorImg: 'https://www.cars-data.com/pictures/peugeot/peugeot-308_3955_1.jpg',
738
+ engineSound: 'https://www.soundjay.com/mechanical/sounds/car-engine-1.mp3',
739
+ hornSound: 'https://www.soundjay.com/mechanical/sounds/car-horn-1.mp3'
740
  },
741
  'bmw-serie3': {
742
  maxSpeed: 250,
743
  acceleration: 0.07,
744
  deceleration: 0.12,
745
  mass: 1450,
746
+ interiorImg: 'https://www.bmw.fr/content/dam/bmw/marketFR/bmw_fr/all-models/3-series/sedan/2021/interior-and-exterior/bmw-3-series-sedan-interior-design-sp-desktop.jpg',
747
+ engineSound: 'https://www.soundjay.com/mechanical/sounds/car-engine-2.mp3',
748
+ hornSound: 'https://www.soundjay.com/mechanical/sounds/car-horn-2.mp3'
749
  },
750
  'audi-a4': {
751
  maxSpeed: 240,
752
  acceleration: 0.06,
753
  deceleration: 0.11,
754
  mass: 1400,
755
+ interiorImg: 'https://www.audi.fr/content/dam/nemo/models/a4/a4-sedan/my-2022/1920x1080-mtc-xxl/1920x1080-a4-sedan-2022_2.jpg',
756
+ engineSound: 'https://www.soundjay.com/mechanical/sounds/car-engine-3.mp3',
757
+ hornSound: 'https://www.soundjay.com/mechanical/sounds/car-horn-3.mp3'
758
+ },
759
+ 'tesla-model3': {
760
+ maxSpeed: 260,
761
+ acceleration: 0.09,
762
+ deceleration: 0.15,
763
+ mass: 1600,
764
+ interiorImg: 'https://www.tesla.com/sites/default/files/model3-new/social/model-3-hero-social.jpg',
765
+ engineSound: 'https://www.soundjay.com/mechanical/sounds/electric-car-1.mp3',
766
+ hornSound: 'https://www.soundjay.com/mechanical/sounds/car-horn-4.mp3'
767
  }
768
  },
769
  environments: {
 
773
  'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Paris_Rue_de_Rivoli.jpg/1200px-Paris_Rue_de_Rivoli.jpg',
774
  'https://cdn.getyourguide.com/img/location/5c9f1b2e82550.jpeg/88.jpg',
775
  'https://www.sortiraparis.com/images/80/83517/577341-visuel-paris-rue-de-sevigne.jpg'
776
+ ],
777
+ mirrorImages: [
778
+ 'https://www.parisinfo.com/var/otcp/sites/images/media/1.-photos/02.-ville-culture-loisirs/03.-paris-au-fil-de-l-eau/paris-rue-de-rivoli-630x405-c-thinkstock/1200x630-rue-de-rivoli-%7C-630x405-%7C-%C2%A9-thinkstock.jpg',
779
+ 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Paris_Rue_de_Rivoli.jpg/1200px-Paris_Rue_de_Rivoli.jpg'
780
  ]
781
  },
782
  'autoroute': {
 
784
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg',
785
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg',
786
  'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg'
787
+ ],
788
+ mirrorImages: [
789
+ 'https://www.leparisien.fr/resizer/9g2XZQ1JY6h4j3w7Q3Q6Q3Q6Q3Q=/1200x675/cloudfront-eu-central-1.images.arcpublishing.com/leparisien/5V3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Z3Y.jpg'
790
  ]
791
  },
792
  'provence': {
 
794
  'https://www.provenceweb.fr/f/albums/route-provence.jpg',
795
  'https://www.provenceweb.fr/f/albums/route-provence-2.jpg',
796
  'https://www.provenceweb.fr/f/albums/route-provence-3.jpg'
797
+ ],
798
+ mirrorImages: [
799
+ 'https://www.provenceweb.fr/f/albums/route-provence.jpg',
800
+ 'https://www.provenceweb.fr/f/albums/route-provence-2.jpg'
801
  ]
802
  },
803
  'alpes': {
 
805
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes.jpg',
806
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes-2.jpg',
807
  'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes-3.jpg'
808
+ ],
809
+ mirrorImages: [
810
+ 'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes.jpg',
811
+ 'https://www.alpes-maritimes-tourisme.com/sites/default/files/styles/header/public/2019-06/route-des-grandes-alpes-2.jpg'
812
  ]
813
  }
814
+ },
815
+ weather: {
816
+ 'sunny': {
817
+ lightColor: 'rgba(255,240,200,0.3)',
818
+ roadWetness: 0,
819
+ visibility: 1
820
+ },
821
+ 'rainy': {
822
+ lightColor: 'rgba(150,180,255,0.2)',
823
+ roadWetness: 1,
824
+ visibility: 0.7
825
+ },
826
+ 'night': {
827
+ lightColor: 'rgba(100,120,255,0.4)',
828
+ roadWetness: 0.3,
829
+ visibility: 0.5
830
+ }
831
  }
832
  };
833
 
834
  // État du jeu
835
  const gameState = {
836
  active: false,
837
+ vehicle: 'peugeot-308',
838
  environment: 'paris',
839
+ weather: 'sunny',
840
  speed: 0,
841
  rpm: 0,
842
  gear: 'N',
843
  steering: 0,
844
  acceleration: 0,
845
  braking: 0,
846
+ clutch: 0,
847
  handbrake: false,
848
  lights: false,
849
  horn: false,
850
+ wipers: false,
851
  fuel: 100,
852
  distance: 0,
853
+ odometer: 0,
854
  startTime: null,
855
  lastUpdate: null,
856
  keys: {},
857
  currentRoadIndex: 0,
858
  engineTemp: 80,
859
+ vibrationIntensity: 0,
860
+ damage: 0,
861
+ timeOfDay: 14.5, // 14:30
862
+ weatherChanged: false
863
  };
864
 
865
  // Fonction pour changer l'image de la route
 
870
  const roadImages = env.roadImages;
871
 
872
  // Changer d'image selon la vitesse
873
+ if (Math.abs(gameState.speed) > 20) {
874
+ const changeInterval = Math.max(100, 500 - (Math.abs(gameState.speed) * 2));
875
+
876
+ if (Date.now() - gameState.lastRoadChange > changeInterval) {
877
+ gameState.currentRoadIndex = (gameState.currentRoadIndex + 1) % roadImages.length;
878
+ document.getElementById('road-view').style.backgroundImage = `url(${roadImages[gameState.currentRoadIndex]})`;
879
+
880
+ // Mettre à jour les rétroviseurs avec un léger délai
881
+ setTimeout(() => {
882
+ const mirrorImg = env.mirrorImages[gameState.currentRoadIndex % env.mirrorImages.length];
883
+ document.getElementById('left-mirror').style.backgroundImage = `url(${mirrorImg})`;
884
+ document.getElementById('right-mirror').style.backgroundImage = `url(${mirrorImg})`;
885
+ document.getElementById('rear-mirror').style.backgroundImage = `url(${mirrorImg})`;
886
+ }, 100);
887
+
888
+ gameState.lastRoadChange = Date.now();
889
+ }
890
  }
891
  }
892
 
893
  // Animation du jeu
894
  function animate() {
895
  if (gameState.active) {
896
+ updateTimeAndWeather();
897
  updatePhysics();
898
  updateVehicle();
899
  updateRoadView();
900
  updateUI();
901
  updateVibration();
902
+ updateSound();
903
+ updateEffects();
904
  }
905
 
906
  requestAnimationFrame(animate);
907
  }
908
 
909
+ function updateTimeAndWeather() {
910
+ // Avancer le temps (1 minute de jeu = 1 seconde réelle)
911
+ gameState.timeOfDay += (1/60) * 0.1;
912
+ if (gameState.timeOfDay >= 24) gameState.timeOfDay = 0;
913
+
914
+ // Mettre à jour l'affichage de l'heure
915
+ const hours = Math.floor(gameState.timeOfDay);
916
+ const minutes = Math.floor((gameState.timeOfDay % 1) * 60);
917
+ document.getElementById('real-time').textContent =
918
+ `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
919
+
920
+ // Changer la luminosité selon l'heure
921
+ let lightIntensity = 0;
922
+ if (gameState.timeOfDay > 5 && gameState.timeOfDay < 19) {
923
+ // Journée
924
+ lightIntensity = 1 - Math.abs(12 - gameState.timeOfDay) / 7;
925
+ } else {
926
+ // Nuit
927
+ lightIntensity = 0.2;
928
+ }
929
+
930
+ // Mettre à jour l'icône météo
931
+ const weatherIcon = document.getElementById('weather-icon');
932
+ if (gameState.weather === 'rainy') {
933
+ weatherIcon.innerHTML = '<i class="fas fa-cloud-rain"></i>';
934
+ } else if (gameState.timeOfDay > 6 && gameState.timeOfDay < 20) {
935
+ weatherIcon.innerHTML = '<i class="fas fa-sun"></i>';
936
+ } else {
937
+ weatherIcon.innerHTML = '<i class="fas fa-moon"></i>';
938
+ }
939
+
940
+ // Changement aléatoire de météo
941
+ if (Math.random() < 0.0005 && !gameState.weatherChanged) {
942
+ const weatherTypes = Object.keys(config.weather);
943
+ gameState.weather = weatherTypes[Math.floor(Math.random() * weatherTypes.length)];
944
+ gameState.weatherChanged = true;
945
+
946
+ // Arrêter le changement pendant un moment
947
+ setTimeout(() => {
948
+ gameState.weatherChanged = false;
949
+ }, 30000);
950
+ }
951
+ }
952
+
953
  function updatePhysics() {
954
  const now = new Date();
955
  const deltaTime = (now - gameState.lastUpdate) / 1000; // en secondes
 
957
 
958
  if (deltaTime > 0.1) return; // Éviter les sauts de temps trop grands
959
 
960
+ // Effets de la météo sur la conduite
961
+ const weatherEffects = config.weather[gameState.weather];
962
+ const wetnessFactor = 1 - (weatherEffects.roadWetness * 0.2);
963
+
964
  // Mise à jour de la position et de la vitesse
965
  if (gameState.gear !== 'N') {
966
  // Accélération
967
  if (gameState.acceleration > 0) {
968
  if (gameState.gear === 'R') {
969
+ gameState.speed -= config.vehicles[gameState.vehicle].acceleration * deltaTime * 0.5 * wetnessFactor;
970
  } else {
971
+ gameState.speed += config.vehicles[gameState.vehicle].acceleration * deltaTime * wetnessFactor;
972
  }
973
  }
974
 
975
  // Freinage
976
  if (gameState.braking > 0) {
977
+ gameState.speed -= config.vehicles[gameState.vehicle].deceleration * deltaTime * (1 + weatherEffects.roadWetness * 0.5);
978
  }
979
 
980
  // Frein à main
981
  if (gameState.handbrake) {
982
+ gameState.speed *= 0.92;
983
+ if (Math.abs(gameState.speed) > 10) {
984
+ // Créer des effets de dérapage
985
+ gameState.damage += 0.001;
986
+ document.getElementById('tire-sound').volume = Math.min(0.5, Math.abs(gameState.speed) / 100);
987
+ document.getElementById('tire-sound').play();
988
+ }
989
  }
990
 
991
  // Décélération naturelle
992
  if (gameState.acceleration === 0 && gameState.braking === 0 && !gameState.handbrake) {
993
+ gameState.speed *= config.physics.friction * wetnessFactor;
994
+ }
995
+
996
+ // Effet de direction
997
+ if (gameState.steering !== 0) {
998
+ const turnFactor = gameState.steering * (Math.abs(gameState.speed) / 100) * deltaTime * 10;
999
+ document.getElementById('road-view').style.transform = `translate(0, 0) rotate(${turnFactor}deg)`;
1000
+
1001
+ // Perte d'adhérence si on tourne trop vite
1002
+ if (Math.abs(turnFactor) > 1 && Math.abs(gameState.speed) > 50) {
1003
+ gameState.speed *= 0.98;
1004
+ gameState.damage += 0.0005;
1005
+ }
1006
+ } else {
1007
+ document.getElementById('road-view').style.transform = 'translate(0, 0) rotate(0)';
1008
  }
1009
 
1010
  // Limite de vitesse selon la marche
 
1029
  gameState.engineTemp += (gameState.rpm - 2) * deltaTime * 2;
1030
  gameState.engineTemp = Math.max(60, Math.min(gameState.engineTemp, 120));
1031
 
1032
+ // Surchauffe si RPM trop haut
1033
+ if (gameState.rpm > 7) {
1034
+ gameState.engineTemp += deltaTime * 5;
1035
+ gameState.damage += deltaTime * 0.001;
1036
+ }
1037
+
1038
  // Consommation de carburant
1039
  gameState.fuel -= (gameState.rpm / 100) * deltaTime;
1040
  gameState.fuel = Math.max(0, gameState.fuel);
1041
 
1042
  if (gameState.fuel <= 0) {
1043
  gameState.speed *= 0.98; // Ralentir si plus de carburant
1044
+ gameState.rpm = 0;
1045
  }
1046
  } else { // Point mort
1047
  gameState.rpm = 0.5;
1048
+ gameState.speed *= 0.92; // Ralentir plus vite en point mort
1049
  gameState.engineTemp = Math.max(60, gameState.engineTemp - deltaTime * 5);
1050
  }
1051
 
1052
  // Mise à jour de la distance parcourue
1053
+ const distanceDelta = (Math.abs(gameState.speed) * deltaTime) / 3600; // en km
1054
+ gameState.distance += distanceDelta;
1055
+ gameState.odometer += distanceDelta;
1056
 
1057
  // Intensité des vibrations
1058
+ gameState.vibrationIntensity = Math.min(Math.abs(gameState.speed) / 150, 0.15);
1059
+
1060
+ // Effets de dommage
1061
+ if (gameState.damage > 0.5) {
1062
+ document.getElementById('damage-effects').style.background = `rgba(255,0,0,${(gameState.damage - 0.5) * 0.4})`;
1063
+ }
1064
  }
1065
 
1066
  function updateVehicle() {
1067
  // Rotation du volant
1068
  document.getElementById('steering-wheel').style.transform = `translateX(-50%) rotate(${gameState.steering * 180}deg)`;
1069
+
1070
+ // Animation des pédales
1071
+ document.getElementById('accelerator-pedal').classList.toggle('active', gameState.acceleration > 0);
1072
+ document.getElementById('brake-pedal').classList.toggle('active', gameState.braking > 0);
1073
+ document.getElementById('clutch-pedal').classList.toggle('active', gameState.clutch > 0);
1074
  }
1075
 
1076
  function updateVibration() {
 
1078
  if (gameState.vibrationIntensity > 0.01) {
1079
  const shakeX = Math.sin(Date.now() * 0.01) * gameState.vibrationIntensity;
1080
  const shakeY = Math.sin(Date.now() * 0.007) * gameState.vibrationIntensity * 0.5;
1081
+ document.getElementById('road-view').style.transform = `translate(${shakeX}px, ${shakeY}px) rotate(0)`;
1082
  document.getElementById('car-interior').style.transform = `translate(${shakeX * 0.5}px, ${shakeY * 0.5}px)`;
1083
+
1084
+ // Effet de lignes de vitesse
1085
+ document.getElementById('speed-lines').style.opacity = Math.min(0.5, gameState.vibrationIntensity * 5);
1086
+ document.getElementById('speed-lines').style.backgroundSize = `100% ${Math.max(5, 30 - (gameState.speed / 10))}px`;
1087
  } else {
1088
+ document.getElementById('road-view').style.transform = 'translate(0, 0) rotate(0)';
1089
  document.getElementById('car-interior').style.transform = 'translate(0, 0)';
1090
+ document.getElementById('speed-lines').style.opacity = '0';
1091
+ }
1092
+ }
1093
+
1094
+ function updateSound() {
1095
+ // Moteur
1096
+ const engineSound = document.getElementById('engine-sound');
1097
+ if (gameState.active) {
1098
+ engineSound.volume = Math.min(0.5, 0.1 + (gameState.rpm / 15));
1099
+ engineSound.playbackRate = 0.8 + (gameState.rpm / 10);
1100
+ }
1101
+
1102
+ // Klaxon
1103
+ if (gameState.horn) {
1104
+ document.getElementById('horn-sound').play();
1105
+ gameState.horn = false;
1106
+ }
1107
+
1108
+ // Essuie-glaces
1109
+ if (gameState.wipers && gameState.weather === 'rainy') {
1110
+ document.getElementById('rain-sound').volume = 0.3;
1111
+ document.getElementById('rain-sound').play();
1112
+ }
1113
+ }
1114
+
1115
+ function updateEffects() {
1116
+ // Phares
1117
+ if (gameState.lights || gameState.timeOfDay < 6 || gameState.timeOfDay > 18) {
1118
+ const weatherEffects = config.weather[gameState.weather];
1119
+ document.getElementById('headlights').style.opacity = weatherEffects.visibility;
1120
+ document.getElementById('headlights').style.background =
1121
+ `radial-gradient(ellipse at center, ${weatherEffects.lightColor} 0%, rgba(255,240,200,0) 70%)`;
1122
+ } else {
1123
+ document.getElementById('headlights').style.opacity = '0';
1124
+ }
1125
+
1126
+ // Pluie sur le pare-brise
1127
+ if (gameState.weather === 'rainy') {
1128
+ document.getElementById('windshield-drops').style.opacity = '0.6';
1129
+ if (gameState.wipers) {
1130
+ // Effet d'essuie-glace
1131
+ document.getElementById('windshield-drops').style.backgroundPosition =
1132
+ `${(Date.now() / 100) % 100}px ${(Date.now() / 200) % 100}px`;
1133
+ }
1134
+ } else {
1135
+ document.getElementById('windshield-drops').style.opacity = '0';
1136
  }
1137
  }
1138
 
 
1153
 
1154
  // Distance
1155
  document.getElementById('distance-display').textContent = gameState.distance.toFixed(1);
1156
+ document.getElementById('odometer').textContent = Math.round(gameState.odometer);
1157
 
1158
  // Temps
1159
  if (gameState.startTime) {
 
1164
  }
1165
 
1166
  // Température moteur
1167
+ const tempValue = document.getElementById('temp-value');
1168
+ tempValue.textContent = Math.round(gameState.engineTemp);
1169
+
1170
  if (gameState.engineTemp > 100) {
1171
+ tempValue.style.color = '#ef4444';
1172
  } else if (gameState.engineTemp > 90) {
1173
+ tempValue.style.color = '#f59e0b';
1174
  } else {
1175
+ tempValue.style.color = 'white';
1176
  }
1177
  }
1178
 
 
1185
 
1186
  // Mettre à jour l'intérieur du véhicule
1187
  document.getElementById('car-interior').style.backgroundImage = `url(${config.vehicles[gameState.vehicle].interiorImg})`;
1188
+
1189
+ // Changer le son du moteur
1190
+ const engineSound = document.getElementById('engine-sound');
1191
+ engineSound.pause();
1192
+ engineSound.src = config.vehicles[gameState.vehicle].engineSound;
1193
+ if (gameState.active) engineSound.play();
1194
+
1195
+ // Changer le son du klaxon
1196
+ document.getElementById('horn-sound').src = config.vehicles[gameState.vehicle].hornSound;
1197
  });
1198
  });
1199
 
1200
  document.querySelectorAll('.environment-btn').forEach(btn => {
1201
  btn.addEventListener('click', () => {
1202
+ if (btn.dataset.env) {
1203
+ document.querySelectorAll('.environment-btn').forEach(b => b.classList.remove('selected'));
1204
+ btn.classList.add('selected');
1205
+ gameState.environment = btn.dataset.env;
1206
+
1207
+ // Mettre à jour la vue de la route
1208
+ const env = config.environments[gameState.environment];
1209
+ document.getElementById('road-view').style.backgroundImage = `url(${env.roadImages[0]})`;
1210
+ gameState.currentRoadIndex = 0;
1211
+ } else if (btn.dataset.weather) {
1212
+ gameState.weather = btn.dataset.weather;
1213
+ document.querySelectorAll('[data-weather]').forEach(b => b.classList.remove('selected'));
1214
+ btn.classList.add('selected');
1215
+ }
1216
  });
1217
  });
1218
 
 
1225
  gameState.active = true;
1226
  gameState.startTime = new Date();
1227
  gameState.lastUpdate = new Date();
1228
+ gameState.lastRoadChange = Date.now();
1229
  gameState.speed = 0;
1230
  gameState.rpm = 0;
1231
  gameState.gear = 'N';
 
1233
  gameState.distance = 0;
1234
  gameState.currentRoadIndex = 0;
1235
  gameState.engineTemp = 80;
1236
+ gameState.damage = 0;
1237
+ gameState.timeOfDay = 14.5; // 14:30
1238
 
1239
  // Masquer le sélecteur de véhicule
1240
  document.querySelector('.vehicle-selector').style.display = 'none';
1241
+ document.querySelector('.environment-selector').style.display = 'none';
1242
 
1243
  // Initialiser la vue de la route
1244
  const env = config.environments[gameState.environment];
1245
  document.getElementById('road-view').style.backgroundImage = `url(${env.roadImages[0]})`;
1246
+
1247
+ // Initialiser les rétroviseurs
1248
+ document.getElementById('left-mirror').style.backgroundImage = `url(${env.mirrorImages[0]})`;
1249
+ document.getElementById('right-mirror').style.backgroundImage = `url(${env.mirrorImages[0]})`;
1250
+ document.getElementById('rear-mirror').style.backgroundImage = `url(${env.mirrorImages[0]})`;
1251
+
1252
+ // Démarrer le son du moteur
1253
+ document.getElementById('engine-sound').play();
1254
  });
1255
 
1256
  document.getElementById('handbrake-btn').addEventListener('click', () => {
 
1261
  document.getElementById('lights-btn').addEventListener('click', () => {
1262
  gameState.lights = !gameState.lights;
1263
  document.getElementById('lights-btn').classList.toggle('bg-yellow-500');
 
1264
  });
1265
 
1266
  document.getElementById('horn-btn').addEventListener('click', () => {
1267
  gameState.horn = true;
1268
  document.getElementById('horn-btn').classList.add('bg-yellow-500');
 
1269
  setTimeout(() => {
 
1270
  document.getElementById('horn-btn').classList.remove('bg-yellow-500');
1271
+ }, 300);
1272
+ });
1273
+
1274
+ document.getElementById('wipers-btn').addEventListener('click', () => {
1275
+ gameState.wipers = !gameState.wipers;
1276
+ document.getElementById('wipers-btn').classList.toggle('bg-blue-500');
1277
  });
1278
 
1279
  // Contrôles clavier
 
1294
  // Freinage
1295
  gameState.braking = gameState.keys['s'] || gameState.keys['arrowdown'] ? 1 : 0;
1296
 
1297
+ // Embrayage
1298
+ gameState.clutch = gameState.keys['c'] ? 1 : 0;
1299
+
1300
  // Direction
1301
  if (gameState.keys['a'] || gameState.keys['arrowleft']) {
1302
  gameState.steering = -1;
 
1338
  if (gameState.keys['h']) {
1339
  gameState.horn = true;
1340
  document.getElementById('horn-btn').classList.add('bg-yellow-500');
 
 
 
1341
  }
1342
 
1343
  // Phares
 
1345
  gameState.lights = !gameState.lights;
1346
  document.getElementById('lights-btn').classList.toggle('bg-yellow-500');
1347
  }
1348
+
1349
+ // Essuie-glaces
1350
+ if (gameState.keys['e']) {
1351
+ gameState.wipers = true;
1352
+ document.getElementById('wipers-btn').classList.add('bg-blue-500');
1353
+ } else {
1354
+ gameState.wipers = false;
1355
+ document.getElementById('wipers-btn').classList.remove('bg-blue-500');
1356
+ }
1357
  }
1358
 
1359
  function changeGear(newGear) {
1360
+ // Vérifier que l'embrayage est enfoncé pour changer de vitesse
1361
+ if (gameState.clutch || gameState.vehicle === 'tesla-model3') {
1362
+ gameState.gear = newGear;
1363
+ document.getElementById('gear-display').textContent = newGear;
1364
+
1365
+ // Petit effet de vibration lors du changement
1366
+ gameState.vibrationIntensity = 0.1;
1367
+ setTimeout(() => {
1368
+ gameState.vibrationIntensity = 0;
1369
+ }, 200);
1370
+ }
1371
  }
1372
 
1373
  // Initialisation
 
1375
  animate();
1376
  document.querySelector('.vehicle-card[data-vehicle="peugeot-308"]').click();
1377
  document.querySelector('.environment-btn[data-env="paris"]').click();
1378
+ document.querySelector('[data-weather="sunny"]').click();
1379
+
1380
+ // Mettre à jour l'heure réelle
1381
+ setInterval(() => {
1382
+ const now = new Date();
1383
+ const hours = now.getHours().toString().padStart(2, '0');
1384
+ const minutes = now.getMinutes().toString().padStart(2, '0');
1385
+ document.getElementById('real-time').textContent = `${hours}:${minutes}`;
1386
+ }, 1000);
1387
  }, 1500);
1388
  </script>
1389
  <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=docto41/ultimate-driving-simulator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
prompts.txt CHANGED
@@ -3,4 +3,5 @@ JE VEUX DES JEUX REEL EN 3D COMME SI ON SE SENT RELLE DEDANT
3
  je veux du visuel reel avec des paysage des personne toute du reel
4
  je veux du vrai paysage avec a linterrieur d'une vrai voiture relle quifibre vraiment avec le simulateur en temp réél
5
  met vision normal pas de vision 3D met toute en relle
6
- je veux voir la vue reel et a l'interrieur de la voiture reel comme si on etait avec toute les vibrasionn avec le volant réelle toute en relle , enleveD POUR ETRE PLUS EN NORMAL VISION NORMAN AVEC TOUTE LE TABLEAU DE BORD COMPLETr de mode 3
 
 
3
  je veux du visuel reel avec des paysage des personne toute du reel
4
  je veux du vrai paysage avec a linterrieur d'une vrai voiture relle quifibre vraiment avec le simulateur en temp réél
5
  met vision normal pas de vision 3D met toute en relle
6
+ je veux voir la vue reel et a l'interrieur de la voiture reel comme si on etait avec toute les vibrasionn avec le volant réelle toute en relle , enleveD POUR ETRE PLUS EN NORMAL VISION NORMAN AVEC TOUTE LE TABLEAU DE BORD COMPLETr de mode 3
7
+ JE VEUX MODE REEL CONDUITE MODE REEL