loftest/barcode-beast
0
1// Game variables2let canvas, ctx;3let gameRunning = false;4let score = 0;5let animationId;6let car = {7 x: 50,8 y: 250,9 width: 60,10 height: 100,11 speed: 5,12 wheelRotation: 013};14let obstacles = [];15let lastObstacleTime = 0;16const obstacleInterval = 1500; // milliseconds17 18// Initialize game19function initGame() {20 canvas = document.getElementById('gameCanvas');21 ctx = canvas.getContext('2d');22 23 // Set canvas dimensions24 const container = document.getElementById('game-container');25 canvas.width = container.clientWidth;26 canvas.height = container.clientHeight;27 28 // Event listeners29 document.getElementById('start-btn').addEventListener('click', startGame);30 document.getElementById('restart-btn').addEventListener('click', startGame);31 32 // Handle keyboard input33 window.addEventListener('keydown', handleKeyDown);34 window.addEventListener('keyup', handleKeyUp);35 36 // Initial render37 render();38}39 40// Start game41function startGame() {42 document.getElementById('start-screen').classList.add('hidden');43 document.getElementById('game-over').classList.add('hidden');44 score = 0;45 document.getElementById('score').textContent = score;46 obstacles = [];47 gameRunning = true;48 lastObstacleTime = Date.now();49 car.y = canvas.height / 2 - car.height / 2;50 gameLoop();51}52 53// Game loop54function gameLoop() {55 if (!gameRunning) return;56 57 update();58 render();59 animationId = requestAnimationFrame(gameLoop);60}61 62// Update game state63function update() {64 // Spawn obstacles65 const currentTime = Date.now();66 if (currentTime - lastObstacleTime > obstacleInterval) {67 spawnObstacle();68 lastObstacleTime = currentTime;69 }70 71 // Move obstacles72 for (let i = obstacles.length - 1; i >= 0; i--) {73 obstacles[i].x -= obstacles[i].speed;74 75 // Check collision76 if (checkCollision(car, obstacles[i])) {77 if (obstacles[i].type === 'snake') {78 score++;79 document.getElementById('score').textContent = score;80 } else {81 gameOver();82 return;83 }84 obstacles.splice(i, 1);85 continue;86 }87 88 // Remove if off screen89 if (obstacles[i].x + obstacles[i].width < 0) {90 obstacles.splice(i, 1);91 }92 }93}94 95// Render game96function render() {97 // Clear canvas98 ctx.clearRect(0, 0, canvas.width, canvas.height);99 // Draw road with perspective effect100 ctx.fillStyle = '#1f2937';101 ctx.fillRect(0, 0, canvas.width, canvas.height);102 103 // Road gradient for depth104 const gradient = ctx.createLinearGradient(0, 0, 0, canvas.height);105 gradient.addColorStop(0, '#374151');106 gradient.addColorStop(1, '#111827');107 ctx.fillStyle = gradient;108 ctx.fillRect(0, 0, canvas.width, canvas.height);109// Draw car110 ctx.fillStyle = '#3b82f6';111 ctx.fillRect(car.x, car.y, car.width, car.height);112 113 // Add car details to make it look like driving114 ctx.fillStyle = '#2563eb';115 ctx.fillRect(car.x + 10, car.y + 10, car.width - 20, car.height - 20);116 117 // Windows118 ctx.fillStyle = '#93c5fd';119 ctx.fillRect(car.x + 15, car.y + 15, car.width - 30, 20);120 ctx.fillRect(car.x + 15, car.y + 50, car.width - 30, 20);121 // Wheels with rotation effect122 ctx.save();123 ctx.fillStyle = '#111827';124 ctx.translate(car.x + 15, car.y + car.height - 10);125 ctx.rotate(car.wheelRotation);126 ctx.beginPath();127 ctx.arc(0, 0, 10, 0, Math.PI * 2);128 ctx.fill();129 ctx.fillStyle = '#4b5563';130 ctx.beginPath();131 ctx.arc(0, 0, 6, 0, Math.PI * 2);132 ctx.fill();133 ctx.restore();134 135 ctx.save();136 ctx.translate(car.x + car.width - 15, car.y + car.height - 10);137 ctx.rotate(car.wheelRotation);138 ctx.fillStyle = '#111827';139 ctx.beginPath();140 ctx.arc(0, 0, 10, 0, Math.PI * 2);141 ctx.fill();142 ctx.fillStyle = '#4b5563';143 ctx.beginPath();144 ctx.arc(0, 0, 6, 0, Math.PI * 2);145 ctx.fill();146 ctx.restore();147 148 // Update wheel rotation based on speed149 car.wheelRotation += car.speed * 0.05;150// Moving effect - road lines passing by151 ctx.strokeStyle = '#e5e7eb';152 ctx.lineWidth = 5;153 ctx.setLineDash([20, 30]);154 const animationOffset = Date.now() % 1000 / 1000 * 50;155 for (let y = -20 + animationOffset; y < canvas.height; y += 50) {156 ctx.beginPath();157 ctx.moveTo(canvas.width / 3, y);158 ctx.lineTo(canvas.width / 3, y + 20);159 ctx.moveTo(canvas.width * 2 / 3, y);160 ctx.lineTo(canvas.width * 2 / 3, y + 20);161 ctx.stroke();162 }163// Draw obstacles164 obstacles.forEach(obstacle => {165 ctx.fillStyle = obstacle.type === 'snake' ? '#10b981' : '#ef4444';166 ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);167 });168}169 170// Spawn obstacle171function spawnObstacle() {172 const obstacleTypes = ['snake', 'snake', 'snake', 'deer']; // Higher chance for snakes173 const type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];174 const laneWidth = canvas.width / 3;175 const lane = Math.floor(Math.random() * 3);176 177 obstacles.push({178 x: canvas.width,179 y: lane * laneWidth + (laneWidth / 2) - 25,180 width: 50,181 height: 50,182 speed: 5 + Math.random() * 3,183 type: type184 });185}186 187// Check collision188function checkCollision(rect1, rect2) {189 return (190 rect1.x < rect2.x + rect2.width &&191 rect1.x + rect1.width > rect2.x &&192 rect1.y < rect2.y + rect2.height &&193 rect1.y + rect1.height > rect2.y194 );195}196 197// Game over198function gameOver() {199 gameRunning = false;200 cancelAnimationFrame(animationId);201 document.getElementById('final-score').textContent = score;202 document.getElementById('game-over').classList.remove('hidden');203}204 205// Handle keyboard input206const keys = {207 ArrowUp: false,208 ArrowDown: false209};210 211function handleKeyDown(e) {212 if (['ArrowUp', 'ArrowDown'].includes(e.key)) {213 keys[e.key] = true;214 e.preventDefault();215 }216}217 218function handleKeyUp(e) {219 if (['ArrowUp', 'ArrowDown'].includes(e.key)) {220 keys[e.key] = false;221 e.preventDefault();222 }223}224 225// Update car position based on keys226function updateCarPosition() {227 if (keys.ArrowUp && car.y > 0) {228 car.y -= car.speed;229 }230 if (keys.ArrowDown && car.y + car.height < canvas.height) {231 car.y += car.speed;232 }233}234 235// Initialize game when DOM is loaded236document.addEventListener('DOMContentLoaded', initGame);237 238// Handle window resize239window.addEventListener('resize', () => {240 const container = document.getElementById('game-container');241 canvas.width = container.clientWidth;242 canvas.height = container.clientHeight;243 render();244});245 246// Update car position continuously247setInterval(() => {248 if (gameRunning) {249 updateCarPosition();250 }251}, 16);