Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Cyber Car Racing</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&display=swap'); | |
| body { | |
| font-family: 'Orbitron', sans-serif; | |
| background-color: #0f0f1a; | |
| overflow: hidden; | |
| color: #00fffc; | |
| } | |
| .track { | |
| background: linear-gradient(90deg, #111122 0%, #111122 50%, #222233 50%, #222233 100%); | |
| background-size: 50px 100%; | |
| } | |
| .car { | |
| transition: transform 0.1s ease-out; | |
| } | |
| .obstacle { | |
| animation: obstacleMove linear infinite; | |
| } | |
| @keyframes obstacleMove { | |
| from { transform: translateY(-100px); } | |
| to { transform: translateY(100vh); } | |
| } | |
| .glow { | |
| text-shadow: 0 0 10px #00fffc, 0 0 20px #00fffc; | |
| } | |
| .pulse { | |
| animation: pulse 1.5s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| 100% { opacity: 1; } | |
| } | |
| .road-mark { | |
| position: absolute; | |
| width: 10px; | |
| height: 50px; | |
| background: #00fffc; | |
| box-shadow: 0 0 10px #00fffc; | |
| } | |
| .highscore-table { | |
| background: rgba(15, 15, 26, 0.9); | |
| border: 2px solid #00fffc; | |
| box-shadow: 0 0 20px #00fffc; | |
| } | |
| .highscore-table th { | |
| background: rgba(0, 255, 252, 0.2); | |
| } | |
| .highscore-table tr:nth-child(even) { | |
| background: rgba(0, 255, 252, 0.05); | |
| } | |
| .highscore-table tr:hover { | |
| background: rgba(0, 255, 252, 0.1); | |
| } | |
| .tab-button { | |
| transition: all 0.3s ease; | |
| } | |
| .tab-button.active { | |
| background: rgba(0, 255, 252, 0.2); | |
| border-bottom: 2px solid #00fffc; | |
| } | |
| </style> | |
| </head> | |
| <body class="h-screen w-screen flex flex-col items-center justify-center relative overflow-hidden"> | |
| <!-- Main Game Container --> | |
| <div id="gameContainer" class="relative w-full h-full"> | |
| <!-- Game Over Screen (Hidden Initially) --> | |
| <div id="gameOverScreen" class="absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center z-50 hidden"> | |
| <h1 class="text-6xl font-bold mb-8 text-red-500 glow">GAME OVER</h1> | |
| <p class="text-2xl mb-4">Your Score: <span id="finalScore" class="text-yellow-400">0</span></p> | |
| <div class="mb-8 w-64"> | |
| <label for="playerName" class="block text-lg mb-2">Enter your name:</label> | |
| <input type="text" id="playerName" class="w-full px-4 py-2 bg-gray-800 border border-blue-400 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" maxlength="15" placeholder="Player"> | |
| </div> | |
| <button id="saveScoreBtn" class="px-8 py-4 bg-blue-600 hover:bg-blue-700 rounded-lg text-xl font-bold transition-all transform hover:scale-105 mb-4"> | |
| <i class="fas fa-save mr-2"></i> Save Score | |
| </button> | |
| <button id="restartBtn" class="px-8 py-4 bg-green-600 hover:bg-green-700 rounded-lg text-xl font-bold transition-all transform hover:scale-105"> | |
| <i class="fas fa-redo mr-2"></i> Play Again | |
| </button> | |
| </div> | |
| <!-- Start Screen --> | |
| <div id="startScreen" class="absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center z-40"> | |
| <h1 class="text-6xl md:text-8xl font-bold mb-8 text-blue-400 glow">CYBER RACER</h1> | |
| <div class="flex flex-col items-center mb-12"> | |
| <p class="text-xl md:text-2xl mb-4 text-center max-w-2xl px-4"> | |
| Navigate through the neon-lit cyber highway, avoid obstacles, and survive as long as you can! | |
| </p> | |
| <div class="flex items-center text-yellow-400 text-lg mb-2"> | |
| <i class="fas fa-arrow-left mr-2"></i> | |
| <span>Left Arrow - Move Left</span> | |
| </div> | |
| <div class="flex items-center text-yellow-400 text-lg"> | |
| <i class="fas fa-arrow-right mr-2"></i> | |
| <span>Right Arrow - Move Right</span> | |
| </div> | |
| </div> | |
| <div class="flex space-x-4 mb-8"> | |
| <button id="startBtn" class="px-8 py-4 bg-green-600 hover:bg-green-700 rounded-lg text-2xl font-bold transition-all transform hover:scale-105 pulse"> | |
| <i class="fas fa-play mr-2"></i> Start Race | |
| </button> | |
| <button id="highscoresBtn" class="px-8 py-4 bg-purple-600 hover:bg-purple-700 rounded-lg text-2xl font-bold transition-all transform hover:scale-105"> | |
| <i class="fas fa-trophy mr-2"></i> High Scores | |
| </button> | |
| </div> | |
| </div> | |
| <!-- High Scores Screen --> | |
| <div id="highscoresScreen" class="absolute inset-0 bg-black bg-opacity-80 flex flex-col items-center justify-center z-50 hidden"> | |
| <h1 class="text-6xl font-bold mb-8 text-yellow-400 glow">HIGH SCORES</h1> | |
| <div class="flex mb-6 space-x-2"> | |
| <button id="allTimeTab" class="tab-button px-6 py-2 rounded-t-lg text-lg font-bold active">All-Time</button> | |
| <button id="weeklyTab" class="tab-button px-6 py-2 rounded-t-lg text-lg font-bold">This Week</button> | |
| </div> | |
| <div class="highscore-table w-full max-w-2xl max-h-96 overflow-y-auto rounded-lg mb-8"> | |
| <table class="w-full"> | |
| <thead> | |
| <tr> | |
| <th class="px-6 py-3 text-left">Rank</th> | |
| <th class="px-6 py-3 text-left">Player</th> | |
| <th class="px-6 py-3 text-left">Score</th> | |
| <th class="px-6 py-3 text-left">Date</th> | |
| </tr> | |
| </thead> | |
| <tbody id="highscoresTable"> | |
| <!-- Scores will be inserted here --> | |
| </tbody> | |
| </table> | |
| </div> | |
| <button id="backToMenuBtn" class="px-8 py-4 bg-blue-600 hover:bg-blue-700 rounded-lg text-xl font-bold transition-all transform hover:scale-105"> | |
| <i class="fas fa-arrow-left mr-2"></i> Back to Menu | |
| </button> | |
| </div> | |
| <!-- Game UI --> | |
| <div class="absolute top-0 left-0 right-0 p-4 flex justify-between items-center z-30"> | |
| <div class="flex items-center"> | |
| <div class="bg-black bg-opacity-70 px-4 py-2 rounded-lg mr-4"> | |
| <span class="text-lg">Score:</span> | |
| <span id="score" class="text-2xl font-bold ml-2 text-yellow-400">0</span> | |
| </div> | |
| <div class="bg-black bg-opacity-70 px-4 py-2 rounded-lg"> | |
| <span class="text-lg">High Score:</span> | |
| <span id="highScore" class="text-2xl font-bold ml-2 text-green-400">0</span> | |
| </div> | |
| </div> | |
| <div class="bg-black bg-opacity-70 px-4 py-2 rounded-lg"> | |
| <span class="text-lg">Speed:</span> | |
| <span id="speed" class="text-2xl font-bold ml-2 text-red-400">1x</span> | |
| </div> | |
| </div> | |
| <!-- Track --> | |
| <div id="track" class="track w-full h-full relative overflow-hidden"> | |
| <!-- Road marks will be generated by JavaScript --> | |
| </div> | |
| <!-- Player Car --> | |
| <div id="playerCar" class="car absolute bottom-20 left-1/2 transform -translate-x-1/2 w-16 h-28 z-20"> | |
| <div class="relative w-full h-full"> | |
| <!-- Car body --> | |
| <div class="absolute inset-0 bg-gradient-to-b from-blue-500 to-blue-800 rounded-lg"> | |
| <div class="absolute top-0 left-0 right-0 h-4 bg-blue-300 rounded-t-lg"></div> | |
| <div class="absolute bottom-0 left-0 right-0 h-2 bg-blue-900 rounded-b-lg"></div> | |
| <!-- Neon effect --> | |
| <div class="absolute inset-0 border-2 border-blue-300 rounded-lg opacity-50"></div> | |
| </div> | |
| <!-- Windows --> | |
| <div class="absolute top-2 left-2 right-2 h-8 bg-blue-200 bg-opacity-30 rounded-sm"></div> | |
| <!-- Headlights --> | |
| <div class="absolute bottom-0 left-2 w-4 h-2 bg-yellow-200 rounded-full"></div> | |
| <div class="absolute bottom-0 right-2 w-4 h-2 bg-yellow-200 rounded-full"></div> | |
| <!-- Neon glow --> | |
| <div class="absolute -bottom-2 left-0 right-0 h-1 bg-blue-300 blur-sm"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Game variables | |
| let gameRunning = false; | |
| let score = 0; | |
| let highScore = localStorage.getItem('highScore') || 0; | |
| let speed = 1; | |
| let speedIncreaseInterval; | |
| let obstacleInterval; | |
| let roadMarkInterval; | |
| let playerPosition = 2; // 1: left, 2: center, 3: right | |
| let lanes = [20, 50, 80]; // Percentage positions for lanes | |
| // High scores data | |
| let allTimeHighscores = JSON.parse(localStorage.getItem('allTimeHighscores')) || []; | |
| let weeklyHighscores = JSON.parse(localStorage.getItem('weeklyHighscores')) || []; | |
| let currentTab = 'allTime'; | |
| // DOM elements | |
| const startScreen = document.getElementById('startScreen'); | |
| const gameOverScreen = document.getElementById('gameOverScreen'); | |
| const highscoresScreen = document.getElementById('highscoresScreen'); | |
| const startBtn = document.getElementById('startBtn'); | |
| const highscoresBtn = document.getElementById('highscoresBtn'); | |
| const backToMenuBtn = document.getElementById('backToMenuBtn'); | |
| const restartBtn = document.getElementById('restartBtn'); | |
| const saveScoreBtn = document.getElementById('saveScoreBtn'); | |
| const scoreElement = document.getElementById('score'); | |
| const highScoreElement = document.getElementById('highScore'); | |
| const finalScoreElement = document.getElementById('finalScore'); | |
| const speedElement = document.getElementById('speed'); | |
| const track = document.getElementById('track'); | |
| const playerCar = document.getElementById('playerCar'); | |
| const playerNameInput = document.getElementById('playerName'); | |
| const highscoresTable = document.getElementById('highscoresTable'); | |
| const allTimeTab = document.getElementById('allTimeTab'); | |
| const weeklyTab = document.getElementById('weeklyTab'); | |
| // Initialize high score display | |
| highScoreElement.textContent = highScore; | |
| // Event listeners | |
| startBtn.addEventListener('click', startGame); | |
| highscoresBtn.addEventListener('click', showHighscores); | |
| backToMenuBtn.addEventListener('click', backToMenu); | |
| restartBtn.addEventListener('click', startGame); | |
| saveScoreBtn.addEventListener('click', saveScore); | |
| allTimeTab.addEventListener('click', () => switchTab('allTime')); | |
| weeklyTab.addEventListener('click', () => switchTab('weekly')); | |
| document.addEventListener('keydown', (e) => { | |
| if (!gameRunning) return; | |
| if (e.key === 'ArrowLeft' && playerPosition > 1) { | |
| playerPosition--; | |
| updateCarPosition(); | |
| } else if (e.key === 'ArrowRight' && playerPosition < 3) { | |
| playerPosition++; | |
| updateCarPosition(); | |
| } | |
| }); | |
| // Update car position based on playerPosition | |
| function updateCarPosition() { | |
| playerCar.style.left = `${lanes[playerPosition - 1]}%`; | |
| } | |
| // Start the game | |
| function startGame() { | |
| // Reset game state | |
| gameRunning = true; | |
| score = 0; | |
| speed = 1; | |
| playerPosition = 2; | |
| updateCarPosition(); | |
| // Clear any existing obstacles | |
| document.querySelectorAll('.obstacle').forEach(obs => obs.remove()); | |
| document.querySelectorAll('.road-mark').forEach(mark => mark.remove()); | |
| // Update UI | |
| startScreen.classList.add('hidden'); | |
| gameOverScreen.classList.add('hidden'); | |
| highscoresScreen.classList.add('hidden'); | |
| scoreElement.textContent = score; | |
| speedElement.textContent = `${speed}x`; | |
| // Start game loops | |
| speedIncreaseInterval = setInterval(increaseSpeed, 5000); | |
| obstacleInterval = setInterval(createObstacle, 2000 / speed); | |
| roadMarkInterval = setInterval(createRoadMarks, 300); | |
| // Initial road marks | |
| for (let i = 0; i < 5; i++) { | |
| createRoadMarks(i * 200); | |
| } | |
| } | |
| // Increase game speed over time | |
| function increaseSpeed() { | |
| speed += 0.2; | |
| speedElement.textContent = `${speed.toFixed(1)}x`; | |
| // Adjust obstacle creation interval based on speed | |
| clearInterval(obstacleInterval); | |
| obstacleInterval = setInterval(createObstacle, 2000 / speed); | |
| } | |
| // Create road marks (dashed lines) | |
| function createRoadMarks(offset = 0) { | |
| for (let i = 0; i < 3; i++) { | |
| const mark = document.createElement('div'); | |
| mark.className = 'road-mark'; | |
| mark.style.left = `${lanes[i]}%`; | |
| mark.style.top = `-50px`; | |
| mark.style.transform = `translateX(-50%) translateY(${offset}px)`; | |
| track.appendChild(mark); | |
| // Animate the mark | |
| const animation = mark.animate( | |
| [{ top: '-50px' }, { top: '100vh' }], | |
| { duration: 3000 / speed, fill: 'forwards' } | |
| ); | |
| animation.onfinish = () => mark.remove(); | |
| } | |
| } | |
| // Create obstacles | |
| function createObstacle() { | |
| if (!gameRunning) return; | |
| const obstacleTypes = ['car', 'truck', 'barrier']; | |
| const type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)]; | |
| const lane = Math.floor(Math.random() * 3) + 1; | |
| const obstacle = document.createElement('div'); | |
| obstacle.className = `obstacle absolute w-16 h-16 z-10`; | |
| obstacle.style.left = `${lanes[lane - 1]}%`; | |
| obstacle.style.top = '-100px'; | |
| obstacle.style.transform = 'translateX(-50%)'; | |
| // Different obstacle styles | |
| if (type === 'car') { | |
| obstacle.innerHTML = ` | |
| <div class="relative w-full h-full"> | |
| <div class="absolute inset-0 bg-gradient-to-b from-red-500 to-red-800 rounded-lg"> | |
| <div class="absolute top-0 left-0 right-0 h-3 bg-red-300 rounded-t-lg"></div> | |
| <div class="absolute bottom-0 left-0 right-0 h-2 bg-red-900 rounded-b-lg"></div> | |
| <div class="absolute inset-0 border-2 border-red-300 rounded-lg opacity-50"></div> | |
| </div> | |
| <div class="absolute top-1 left-1 right-1 h-4 bg-red-200 bg-opacity-30 rounded-sm"></div> | |
| <div class="absolute -bottom-1 left-0 right-0 h-1 bg-red-300 blur-sm"></div> | |
| </div> | |
| `; | |
| obstacle.style.height = '28px'; | |
| } else if (type === 'truck') { | |
| obstacle.innerHTML = ` | |
| <div class="relative w-full h-full"> | |
| <div class="absolute inset-0 bg-gradient-to-b from-purple-500 to-purple-800 rounded-lg"> | |
| <div class="absolute top-0 left-0 right-0 h-3 bg-purple-300 rounded-t-lg"></div> | |
| <div class="absolute bottom-0 left-0 right-0 h-2 bg-purple-900 rounded-b-lg"></div> | |
| <div class="absolute inset-0 border-2 border-purple-300 rounded-lg opacity-50"></div> | |
| </div> | |
| <div class="absolute top-1 left-1 right-1 h-4 bg-purple-200 bg-opacity-30 rounded-sm"></div> | |
| <div class="absolute -bottom-1 left-0 right-0 h-1 bg-purple-300 blur-sm"></div> | |
| </div> | |
| `; | |
| obstacle.style.height = '40px'; | |
| } else { // barrier | |
| obstacle.innerHTML = ` | |
| <div class="relative w-full h-full flex items-center justify-center"> | |
| <div class="w-4 h-8 bg-yellow-500 border-2 border-yellow-300"></div> | |
| <div class="w-4 h-8 bg-yellow-500 border-2 border-yellow-300 ml-1"></div> | |
| <div class="w-4 h-8 bg-yellow-500 border-2 border-yellow-300 ml-1"></div> | |
| </div> | |
| `; | |
| obstacle.style.height = '32px'; | |
| } | |
| track.appendChild(obstacle); | |
| // Animate obstacle | |
| const animation = obstacle.animate( | |
| [{ top: '-100px' }, { top: '100vh' }], | |
| { duration: 4000 / speed, fill: 'forwards' } | |
| ); | |
| animation.onfinish = () => { | |
| if (!gameRunning) return; | |
| obstacle.remove(); | |
| increaseScore(); | |
| }; | |
| // Collision detection | |
| const collisionCheck = setInterval(() => { | |
| if (!gameRunning) { | |
| clearInterval(collisionCheck); | |
| return; | |
| } | |
| const obstacleRect = obstacle.getBoundingClientRect(); | |
| const playerRect = playerCar.getBoundingClientRect(); | |
| if ( | |
| obstacleRect.bottom >= playerRect.top && | |
| obstacleRect.top <= playerRect.bottom && | |
| obstacleRect.right >= playerRect.left && | |
| obstacleRect.left <= playerRect.right | |
| ) { | |
| gameOver(); | |
| clearInterval(collisionCheck); | |
| } | |
| }, 16); | |
| } | |
| // Increase score | |
| function increaseScore() { | |
| score += Math.floor(speed * 10); | |
| scoreElement.textContent = score; | |
| } | |
| // Game over | |
| function gameOver() { | |
| gameRunning = false; | |
| // Clear intervals | |
| clearInterval(speedIncreaseInterval); | |
| clearInterval(obstacleInterval); | |
| clearInterval(roadMarkInterval); | |
| // Update high score if needed | |
| if (score > highScore) { | |
| highScore = score; | |
| localStorage.setItem('highScore', highScore); | |
| highScoreElement.textContent = highScore; | |
| } | |
| // Show game over screen | |
| finalScoreElement.textContent = score; | |
| gameOverScreen.classList.remove('hidden'); | |
| // Explosion effect | |
| const explosion = document.createElement('div'); | |
| explosion.className = 'absolute w-32 h-32 bg-red-500 rounded-full opacity-70 z-30'; | |
| explosion.style.left = `${playerCar.offsetLeft - 32}px`; | |
| explosion.style.top = `${playerCar.offsetTop - 32}px`; | |
| explosion.style.transform = 'scale(0)'; | |
| explosion.style.transition = 'transform 0.5s ease-out'; | |
| track.appendChild(explosion); | |
| setTimeout(() => { | |
| explosion.style.transform = 'scale(1)'; | |
| explosion.style.opacity = '0'; | |
| }, 10); | |
| setTimeout(() => explosion.remove(), 1000); | |
| } | |
| // Show highscores screen | |
| function showHighscores() { | |
| startScreen.classList.add('hidden'); | |
| highscoresScreen.classList.remove('hidden'); | |
| updateHighscoresTable(); | |
| } | |
| // Back to menu from highscores | |
| function backToMenu() { | |
| highscoresScreen.classList.add('hidden'); | |
| startScreen.classList.remove('hidden'); | |
| } | |
| // Switch between all-time and weekly highscores | |
| function switchTab(tab) { | |
| currentTab = tab; | |
| // Update active tab styling | |
| allTimeTab.classList.remove('active'); | |
| weeklyTab.classList.remove('active'); | |
| if (tab === 'allTime') { | |
| allTimeTab.classList.add('active'); | |
| } else { | |
| weeklyTab.classList.add('active'); | |
| } | |
| updateHighscoresTable(); | |
| } | |
| // Update highscores table | |
| function updateHighscoresTable() { | |
| const scores = currentTab === 'allTime' ? allTimeHighscores : weeklyHighscores; | |
| highscoresTable.innerHTML = ''; | |
| if (scores.length === 0) { | |
| const row = document.createElement('tr'); | |
| row.innerHTML = ` | |
| <td colspan="4" class="px-6 py-4 text-center text-gray-400">No scores yet</td> | |
| `; | |
| highscoresTable.appendChild(row); | |
| return; | |
| } | |
| scores.slice(0, 10).forEach((score, index) => { | |
| const row = document.createElement('tr'); | |
| row.className = 'hover:bg-blue-900 hover:bg-opacity-20'; | |
| const date = new Date(score.date); | |
| const formattedDate = date.toLocaleDateString(); | |
| row.innerHTML = ` | |
| <td class="px-6 py-4">${index + 1}</td> | |
| <td class="px-6 py-4">${score.name}</td> | |
| <td class="px-6 py-4">${score.score}</td> | |
| <td class="px-6 py-4">${formattedDate}</td> | |
| `; | |
| highscoresTable.appendChild(row); | |
| }); | |
| } | |
| // Save score to highscores | |
| function saveScore() { | |
| const playerName = playerNameInput.value.trim() || 'Player'; | |
| const currentDate = new Date(); | |
| // Add to all-time highscores | |
| allTimeHighscores.push({ | |
| name: playerName, | |
| score: score, | |
| date: currentDate | |
| }); | |
| // Sort and keep top 10 | |
| allTimeHighscores.sort((a, b) => b.score - a.score); | |
| allTimeHighscores = allTimeHighscores.slice(0, 10); | |
| localStorage.setItem('allTimeHighscores', JSON.stringify(allTimeHighscores)); | |
| // Check if this score is from this week | |
| const oneWeekAgo = new Date(); | |
| oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); | |
| if (currentDate > oneWeekAgo) { | |
| weeklyHighscores.push({ | |
| name: playerName, | |
| score: score, | |
| date: currentDate | |
| }); | |
| // Sort and keep top 10 | |
| weeklyHighscores.sort((a, b) => b.score - a.score); | |
| weeklyHighscores = weeklyHighscores.slice(0, 10); | |
| localStorage.setItem('weeklyHighscores', JSON.stringify(weeklyHighscores)); | |
| } | |
| // Update display | |
| updateHighscoresTable(); | |
| // Show highscores | |
| gameOverScreen.classList.add('hidden'); | |
| highscoresScreen.classList.remove('hidden'); | |
| } | |
| </script> | |
| <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=HammadRehman/hammad-s-space" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |