Okwutecloud commited on
Commit
c96693a
·
verified ·
1 Parent(s): 5b76f58

Nah make it a motorsport game

Browse files
Files changed (1) hide show
  1. f1game.html +209 -109
f1game.html CHANGED
@@ -1,9 +1,10 @@
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>F1 Racing Game</title>
7
  <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
  <script src="https://cdn.tailwindcss.com"></script>
9
  <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
@@ -14,31 +15,45 @@
14
  overflow: hidden;
15
  font-family: 'Arial', sans-serif;
16
  }
17
- .game-container {
18
- background-image: url('http://static.photos/sport/1200x630/10');
19
- background-size: cover;
20
- background-position: center;
21
- height: 100vh;
22
  position: relative;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
  .car {
25
  position: absolute;
26
- width: 100px;
27
- height: 200px;
28
  background-image: url('http://static.photos/automotive/200x200/1');
29
  background-size: contain;
30
  background-repeat: no-repeat;
31
  bottom: 50px;
32
  left: 50%;
33
  transform: translateX(-50%);
 
34
  }
35
- .obstacle {
36
  position: absolute;
37
  width: 80px;
38
- height: 120px;
39
  background-image: url('http://static.photos/automotive/200x200/2');
40
  background-size: contain;
41
  background-repeat: no-repeat;
 
42
  }
43
  .score-board {
44
  position: absolute;
@@ -48,6 +63,7 @@
48
  padding: 10px;
49
  border-radius: 5px;
50
  border-left: 4px solid #E10600;
 
51
  }
52
  .game-over {
53
  position: absolute;
@@ -59,6 +75,7 @@
59
  border-radius: 10px;
60
  text-align: center;
61
  display: none;
 
62
  }
63
  .controls {
64
  position: absolute;
@@ -67,6 +84,7 @@
67
  display: flex;
68
  justify-content: center;
69
  gap: 20px;
 
70
  }
71
  .control-btn {
72
  background-color: #E10600;
@@ -77,22 +95,49 @@
77
  font-size: 20px;
78
  cursor: pointer;
79
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
  </style>
81
  </head>
82
  <body>
83
- <div class="game-container" id="gameArea">
 
 
 
84
  <div class="score-board">
85
- <h3 class="font-bold">SCORE: <span id="score">0</span></h3>
86
- <p>HIGH SCORE: <span id="highScore">0</span></p>
 
 
 
 
 
87
  </div>
88
 
89
  <div class="car" id="playerCar"></div>
90
 
91
  <div class="game-over" id="gameOver">
92
- <h2 class="text-3xl font-bold text-red-500 mb-4">GAME OVER</h2>
93
- <p class="text-xl mb-6">Your Score: <span id="finalScore">0</span></p>
 
94
  <button id="restartBtn" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-6 rounded">
95
- Play Again
96
  </button>
97
  </div>
98
 
@@ -106,146 +151,201 @@
106
  feather.replace();
107
 
108
  // Game variables
109
- let score = 0;
110
- let highScore = localStorage.getItem('f1HighScore') || 0;
 
 
 
111
  let gameSpeed = 5;
112
- let isGameOver = false;
113
- let obstacles = [];
114
  let animationId;
 
115
 
116
  // DOM elements
117
  const gameArea = document.getElementById('gameArea');
 
118
  const playerCar = document.getElementById('playerCar');
119
- const scoreElement = document.getElementById('score');
120
- const highScoreElement = document.getElementById('highScore');
121
- const finalScoreElement = document.getElementById('finalScore');
 
 
 
122
  const gameOverElement = document.getElementById('gameOver');
123
  const restartBtn = document.getElementById('restartBtn');
124
  const leftBtn = document.getElementById('leftBtn');
125
  const rightBtn = document.getElementById('rightBtn');
126
 
127
- // Set high score display
128
- highScoreElement.textContent = highScore;
129
-
130
- // Player car position
131
- let carPosition = 50; // percentage from left
132
-
133
- // Keyboard controls
134
- document.addEventListener('keydown', (e) => {
135
- if (e.key === 'ArrowLeft' && carPosition > 10) {
136
- carPosition -= 10;
137
- } else if (e.key === 'ArrowRight' && carPosition < 90) {
138
- carPosition += 10;
139
- }
140
- updateCarPosition();
141
- });
142
 
143
- // Touch controls
144
- leftBtn.addEventListener('click', () => {
145
- if (carPosition > 10) {
146
- carPosition -= 10;
147
- updateCarPosition();
 
 
 
 
 
 
 
 
 
148
  }
149
- });
 
 
150
 
151
- rightBtn.addEventListener('click', () => {
152
- if (carPosition < 90) {
153
- carPosition += 10;
154
- updateCarPosition();
155
- }
156
- });
157
 
158
- function updateCarPosition() {
159
- playerCar.style.left = `${carPosition}%`;
 
 
 
 
160
  }
161
 
162
- // Create obstacles
163
- function createObstacle() {
164
- if (isGameOver) return;
165
-
166
- const obstacle = document.createElement('div');
167
- obstacle.className = 'obstacle';
168
- obstacle.style.left = `${Math.random() * 80 + 10}%`;
169
- obstacle.style.top = '-120px';
170
- gameArea.appendChild(obstacle);
171
- obstacles.push(obstacle);
172
-
173
- setTimeout(createObstacle, Math.random() * 2000 + 1000);
 
 
 
174
  }
175
 
176
- // Move obstacles
177
- function moveObstacles() {
178
- obstacles.forEach((obstacle, index) => {
179
- const obstacleTop = parseInt(obstacle.style.top) + gameSpeed;
180
- obstacle.style.top = `${obstacleTop}px`;
181
 
182
- // Check collision
183
- if (obstacleTop > gameArea.offsetHeight - 200 &&
184
- obstacleTop < gameArea.offsetHeight - 50 &&
185
- Math.abs(parseInt(obstacle.style.left) - carPosition) < 10) {
186
- gameOver();
187
  }
188
 
189
- // Remove obstacle when off screen
190
- if (obstacleTop > gameArea.offsetHeight) {
191
- obstacle.remove();
192
- obstacles.splice(index, 1);
193
- score++;
194
- scoreElement.textContent = score;
195
-
196
- // Increase speed every 5 points
197
- if (score % 5 === 0) {
198
- gameSpeed += 0.5;
199
- }
200
  }
201
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
 
203
- if (!isGameOver) {
204
- animationId = requestAnimationFrame(moveObstacles);
 
 
 
 
 
 
205
  }
206
  }
207
 
208
- // Game over function
209
- function gameOver() {
210
- isGameOver = true;
211
  cancelAnimationFrame(animationId);
212
 
213
- // Update high score
214
- if (score > highScore) {
215
- highScore = score;
216
- localStorage.setItem('f1HighScore', highScore);
217
- highScoreElement.textContent = highScore;
218
- }
219
-
220
- finalScoreElement.textContent = score;
221
  gameOverElement.style.display = 'block';
222
  }
223
 
224
  // Restart game
225
  function restartGame() {
226
- // Clear obstacles
227
- obstacles.forEach(obstacle => obstacle.remove());
228
- obstacles = [];
229
 
230
  // Reset variables
231
- score = 0;
 
232
  gameSpeed = 5;
233
- isGameOver = false;
 
234
 
235
  // Update displays
236
- scoreElement.textContent = score;
 
 
237
  gameOverElement.style.display = 'none';
238
 
239
  // Start game
240
- createObstacle();
241
- moveObstacles();
242
  }
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  restartBtn.addEventListener('click', restartGame);
245
 
246
  // Start game
247
- createObstacle();
248
- moveObstacles();
249
  </script>
250
  </body>
251
- </html>
 
1
+
2
  <!DOCTYPE html>
3
  <html lang="en">
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>F1 Racing Simulator</title>
8
  <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
9
  <script src="https://cdn.tailwindcss.com"></script>
10
  <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
 
15
  overflow: hidden;
16
  font-family: 'Arial', sans-serif;
17
  }
18
+ .track {
 
 
 
 
19
  position: relative;
20
+ height: 100vh;
21
+ width: 100%;
22
+ background-color: #333;
23
+ overflow: hidden;
24
+ }
25
+ .road {
26
+ position: absolute;
27
+ width: 400px;
28
+ height: 200%;
29
+ background-color: #555;
30
+ left: 50%;
31
+ transform: translateX(-50%);
32
+ border-left: 5px dashed #ccc;
33
+ border-right: 5px dashed #ccc;
34
+ background-image: linear-gradient(#777 1px, transparent 1px);
35
+ background-size: 100% 40px;
36
  }
37
  .car {
38
  position: absolute;
39
+ width: 80px;
40
+ height: 160px;
41
  background-image: url('http://static.photos/automotive/200x200/1');
42
  background-size: contain;
43
  background-repeat: no-repeat;
44
  bottom: 50px;
45
  left: 50%;
46
  transform: translateX(-50%);
47
+ z-index: 10;
48
  }
49
+ .opponent {
50
  position: absolute;
51
  width: 80px;
52
+ height: 160px;
53
  background-image: url('http://static.photos/automotive/200x200/2');
54
  background-size: contain;
55
  background-repeat: no-repeat;
56
+ z-index: 5;
57
  }
58
  .score-board {
59
  position: absolute;
 
63
  padding: 10px;
64
  border-radius: 5px;
65
  border-left: 4px solid #E10600;
66
+ z-index: 20;
67
  }
68
  .game-over {
69
  position: absolute;
 
75
  border-radius: 10px;
76
  text-align: center;
77
  display: none;
78
+ z-index: 30;
79
  }
80
  .controls {
81
  position: absolute;
 
84
  display: flex;
85
  justify-content: center;
86
  gap: 20px;
87
+ z-index: 20;
88
  }
89
  .control-btn {
90
  background-color: #E10600;
 
95
  font-size: 20px;
96
  cursor: pointer;
97
  }
98
+ .lap-time {
99
+ position: absolute;
100
+ top: 20px;
101
+ right: 20px;
102
+ background-color: rgba(0,0,0,0.7);
103
+ padding: 10px;
104
+ border-radius: 5px;
105
+ border-right: 4px solid #E10600;
106
+ z-index: 20;
107
+ }
108
+ .grass {
109
+ position: absolute;
110
+ width: 100%;
111
+ height: 200%;
112
+ background-color: #2a5c2a;
113
+ background-image: url('http://static.photos/nature/200x200/5');
114
+ background-size: 200px;
115
+ }
116
  </style>
117
  </head>
118
  <body>
119
+ <div class="track" id="gameArea">
120
+ <div class="grass"></div>
121
+ <div class="road"></div>
122
+
123
  <div class="score-board">
124
+ <h3 class="font-bold">LAP: <span id="lap">1</span>/3</h3>
125
+ <p>POSITION: <span id="position">1</span></p>
126
+ </div>
127
+
128
+ <div class="lap-time">
129
+ <h3 class="font-bold">LAP TIME: <span id="time">0:00.000</span></h3>
130
+ <p>BEST: <span id="bestTime">0:00.000</span></p>
131
  </div>
132
 
133
  <div class="car" id="playerCar"></div>
134
 
135
  <div class="game-over" id="gameOver">
136
+ <h2 class="text-3xl font-bold text-red-500 mb-4">RACE FINISHED</h2>
137
+ <p class="text-xl mb-2">Final Position: <span id="finalPosition">1</span></p>
138
+ <p class="text-xl mb-4">Best Lap: <span id="finalBestTime">0:00.000</span></p>
139
  <button id="restartBtn" class="bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-6 rounded">
140
+ New Race
141
  </button>
142
  </div>
143
 
 
151
  feather.replace();
152
 
153
  // Game variables
154
+ let lap = 1;
155
+ let position = 1;
156
+ let lapStartTime = 0;
157
+ let currentLapTime = 0;
158
+ let bestLapTime = 0;
159
  let gameSpeed = 5;
160
+ let isRaceOver = false;
161
+ let opponents = [];
162
  let animationId;
163
+ let roadPosition = 0;
164
 
165
  // DOM elements
166
  const gameArea = document.getElementById('gameArea');
167
+ const road = document.querySelector('.road');
168
  const playerCar = document.getElementById('playerCar');
169
+ const lapElement = document.getElementById('lap');
170
+ const positionElement = document.getElementById('position');
171
+ const timeElement = document.getElementById('time');
172
+ const bestTimeElement = document.getElementById('bestTime');
173
+ const finalPositionElement = document.getElementById('finalPosition');
174
+ const finalBestTimeElement = document.getElementById('finalBestTime');
175
  const gameOverElement = document.getElementById('gameOver');
176
  const restartBtn = document.getElementById('restartBtn');
177
  const leftBtn = document.getElementById('leftBtn');
178
  const rightBtn = document.getElementById('rightBtn');
179
 
180
+ // Initialize game
181
+ function initGame() {
182
+ lapStartTime = Date.now();
183
+ updateLapTime();
184
+ createOpponents();
185
+ requestAnimationFrame(gameLoop);
186
+ }
 
 
 
 
 
 
 
 
187
 
188
+ // Game loop
189
+ function gameLoop() {
190
+ if (isRaceOver) return;
191
+
192
+ // Move road to simulate car moving
193
+ roadPosition += gameSpeed;
194
+ road.style.backgroundPositionY = `${roadPosition}px`;
195
+
196
+ // Move opponents
197
+ moveOpponents();
198
+
199
+ // Check lap completion (simplified)
200
+ if (roadPosition % 5000 < gameSpeed) {
201
+ completeLap();
202
  }
203
+
204
+ animationId = requestAnimationFrame(gameLoop);
205
+ }
206
 
207
+ // Update lap time display
208
+ function updateLapTime() {
209
+ currentLapTime = Date.now() - lapStartTime;
210
+ timeElement.textContent = formatTime(currentLapTime);
211
+ setTimeout(updateLapTime, 10);
212
+ }
213
 
214
+ // Format time (milliseconds to M:SS.mmm)
215
+ function formatTime(ms) {
216
+ const minutes = Math.floor(ms / 60000);
217
+ const seconds = Math.floor((ms % 60000) / 1000);
218
+ const milliseconds = ms % 1000;
219
+ return `${minutes}:${seconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(3, '0')}`;
220
  }
221
 
222
+ // Create AI opponents
223
+ function createOpponents() {
224
+ for (let i = 0; i < 5; i++) {
225
+ const opponent = document.createElement('div');
226
+ opponent.className = 'opponent';
227
+ opponent.style.left = `${Math.random() * 300 + 50}px`;
228
+ opponent.style.top = `${Math.random() * 500}px`;
229
+ gameArea.appendChild(opponent);
230
+ opponents.push({
231
+ element: opponent,
232
+ speed: 3 + Math.random() * 2,
233
+ x: parseInt(opponent.style.left),
234
+ y: parseInt(opponent.style.top)
235
+ });
236
+ }
237
  }
238
 
239
+ // Move AI opponents
240
+ function moveOpponents() {
241
+ opponents.forEach((opponent, index) => {
242
+ opponent.y += opponent.speed;
243
+ opponent.x += Math.sin(Date.now() / 1000 + index) * 2; // side-to-side movement
244
 
245
+ // Wrap around track
246
+ if (opponent.y > gameArea.offsetHeight) {
247
+ opponent.y = -200;
 
 
248
  }
249
 
250
+ opponent.element.style.top = `${opponent.y}px`;
251
+ opponent.element.style.left = `${opponent.x}px`;
252
+
253
+ // Simple collision detection
254
+ if (Math.abs(opponent.x - parseInt(playerCar.style.left)) < 60 &&
255
+ Math.abs(opponent.y - parseInt(playerCar.style.top)) < 100) {
256
+ handleCollision();
 
 
 
 
257
  }
258
  });
259
+ }
260
+
261
+ // Handle collision
262
+ function handleCollision() {
263
+ gameSpeed = Math.max(1, gameSpeed - 1); // Slow down on collision
264
+ }
265
+
266
+ // Complete a lap
267
+ function completeLap() {
268
+ lap++;
269
+ lapElement.textContent = lap;
270
+
271
+ // Update best lap time
272
+ if (currentLapTime < bestLapTime || bestLapTime === 0) {
273
+ bestLapTime = currentLapTime;
274
+ bestTimeElement.textContent = formatTime(bestLapTime);
275
+ }
276
 
277
+ // Increase difficulty
278
+ gameSpeed += 0.5;
279
+
280
+ // Check race completion
281
+ if (lap > 3) {
282
+ finishRace();
283
+ } else {
284
+ lapStartTime = Date.now(); // Reset lap timer
285
  }
286
  }
287
 
288
+ // Finish race
289
+ function finishRace() {
290
+ isRaceOver = true;
291
  cancelAnimationFrame(animationId);
292
 
293
+ finalPositionElement.textContent = position;
294
+ finalBestTimeElement.textContent = formatTime(bestLapTime);
 
 
 
 
 
 
295
  gameOverElement.style.display = 'block';
296
  }
297
 
298
  // Restart game
299
  function restartGame() {
300
+ // Clear opponents
301
+ opponents.forEach(opponent => opponent.element.remove());
302
+ opponents = [];
303
 
304
  // Reset variables
305
+ lap = 1;
306
+ position = 1;
307
  gameSpeed = 5;
308
+ isRaceOver = false;
309
+ roadPosition = 0;
310
 
311
  // Update displays
312
+ lapElement.textContent = lap;
313
+ positionElement.textContent = position;
314
+ timeElement.textContent = '0:00.000';
315
  gameOverElement.style.display = 'none';
316
 
317
  // Start game
318
+ initGame();
 
319
  }
320
 
321
+ // Player car position
322
+ let carX = gameArea.offsetWidth / 2;
323
+
324
+ // Keyboard controls
325
+ document.addEventListener('keydown', (e) => {
326
+ if (e.key === 'ArrowLeft') {
327
+ carX = Math.max(50, carX - 20);
328
+ } else if (e.key === 'ArrowRight') {
329
+ carX = Math.min(gameArea.offsetWidth - 50, carX + 20);
330
+ }
331
+ playerCar.style.left = `${carX}px`;
332
+ });
333
+
334
+ // Touch controls
335
+ leftBtn.addEventListener('click', () => {
336
+ carX = Math.max(50, carX - 20);
337
+ playerCar.style.left = `${carX}px`;
338
+ });
339
+
340
+ rightBtn.addEventListener('click', () => {
341
+ carX = Math.min(gameArea.offsetWidth - 50, carX + 20);
342
+ playerCar.style.left = `${carX}px`;
343
+ });
344
+
345
  restartBtn.addEventListener('click', restartGame);
346
 
347
  // Start game
348
+ initGame();
 
349
  </script>
350
  </body>
351
+ </html>