CoolFace
Apppublic

arthurformat/racer-rush-thunderbolt

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
script.js262 linesDownload Raw Back to root
1class RacingGame {2    constructor() {3        this.canvas = document.getElementById('gameCanvas');4        this.ctx = this.canvas.getContext('2d');5        this.score = 0;6        this.timer = 60;7        this.lives = 3;8        this.gameActive = false;9        this.gameLoop = null;10        11        // Game elements12        this.car = {13            x: this.canvas.width / 2 - 25,14            y: this.canvas.height - 100,15            width: 50,16            height: 80,17            speed: 718        };19        20        this.obstacles = [];21        this.obstacleSpeed = 3;22        this.obstacleFrequency = 120; // frames between obstacles23        24        this.keys = {};25        this.frameCount = 0;26        27        this.init();28    }29    30    init() {31        this.setupEventListeners();32        this.updateDisplay();33        this.startGame();34    }35    36    setupEventListeners() {37        document.addEventListener('keydown', (e) => {38            this.keys[e.key] = true;39        });40        41        document.addEventListener('keyup', (e) => {42            this.keys[e.key] = false;43        });44        45        document.getElementById('restartBtn').addEventListener('click', () => {46            this.restartGame();47        });48        49        // Touch controls for mobile50        this.canvas.addEventListener('touchstart', (e) => {51            const touchX = e.touches[0].clientX - this.canvas.getBoundingClientRect().left;52            if (touchX < this.canvas.width / 2) {53                this.keys['ArrowLeft'] = true;54            } else {55                this.keys['ArrowRight'] = true;56            }57            e.preventDefault();58        });59        60        this.canvas.addEventListener('touchend', (e) => {61            this.keys['ArrowLeft'] = false;62            this.keys['ArrowRight'] = false;63            e.preventDefault();64        });65    }66    67    startGame() {68        this.gameActive = true;69        this.gameLoop = setInterval(() => this.update(), 1000/60); // 60 FPS70        this.startTimer();71    }72    73    startTimer() {74        const timerInterval = setInterval(() => {75            if (this.gameActive && this.timer > 0) {76                this.timer--;77                this.updateDisplay();78            } else if (this.timer <= 0) {79                clearInterval(timerInterval);80                this.gameOver();81            }82        }, 1000);83    }84    85    update() {86        if (!this.gameActive) return;87        88        this.frameCount++;89        this.moveCar();90        this.updateObstacles();91        this.checkCollisions();92        this.draw();93    }94    95    moveCar() {96        if (this.keys['ArrowLeft'] && this.car.x > 50) {97            this.car.x -= this.car.speed;98        }99        if (this.keys['ArrowRight'] && this.car.x < this.canvas.width - this.car.width - 50) {100            this.car.x += this.car.speed;101        }102    }103    104    updateObstacles() {105        // Add new obstacles106        if (this.frameCount % this.obstacleFrequency === 0) {107            this.addObstacle();108        }109        110        // Move obstacles and remove off-screen ones111        this.obstacles = this.obstacles.filter(obstacle => {112            obstacle.y += this.obstacleSpeed;113            return obstacle.y < this.canvas.height;114        });115    }116    117    addObstacle() {118        const width = Math.random() * 60 + 40;119        const x = Math.random() * (this.canvas.width - width - 100) + 50;120        121        this.obstacles.push({122            x: x,123            y: -100,124            width: width,125            height: 60,126            color: this.getRandomObstacleColor()127        });128    }129    130    getRandomObstacleColor() {131        const colors = ['#ef4444', '#f97316', '#eab308', '#22c55e', '#3b82f6', '#8b5cf6'];132        return colors[Math.floor(Math.random() * colors.length)];133    }134    135    checkCollisions() {136        this.obstacles.forEach(obstacle => {137            if (this.isColliding(this.car, obstacle)) {138                this.lives--;139                this.obstacles = this.obstacles.filter(o => o !== obstacle);140                this.updateDisplay();141                142                if (this.lives <= 0) {143                    this.gameOver();144                }145            }146        });147    }148    149    isColliding(rect1, rect2) {150        return rect1.x < rect2.x + rect2.width &&151               rect1.x + rect1.width > rect2.x &&152               rect1.y < rect2.y + rect2.height &&153               rect1.y + rect1.height > rect2.y;154    }155    156    draw() {157        // Clear canvas158        this.ctx.fillStyle = '#1e293b';159        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);160        161        // Draw road162        this.drawRoad();163        164        // Draw obstacles165        this.obstacles.forEach(obstacle => {166            this.drawObstacle(obstacle);167        });168        169        // Draw car170        this.drawCar();171        172        // Update score when obstacles pass173        this.obstacles.forEach(obstacle => {174            if (obstacle.y + obstacle.height > this.car.y + this.car.height && !obstacle.passed) {175                obstacle.passed = true;176                this.score += 10;177                this.updateDisplay();178            }179        });180    }181    182    drawRoad() {183        // Road background184        this.ctx.fillStyle = '#374151';185        this.ctx.fillRect(50, 0, this.canvas.width - 100, this.canvas.height);186        187        // Road lines188        this.ctx.strokeStyle = '#facc15';189        this.ctx.lineWidth = 4;190        this.ctx.setLineDash([20, 20]);191        this.ctx.lineDashOffset = -this.frameCount % 40;192        193        this.ctx.beginPath();194        this.ctx.moveTo(this.canvas.width / 2, 0);195        this.ctx.lineTo(this.canvas.width / 2, this.canvas.height);196        this.ctx.stroke();197        198        this.ctx.setLineDash([]);199        200        // Road borders201        this.ctx.strokeStyle = '#ffffff';202        this.ctx.lineWidth = 2;203        this.ctx.strokeRect(50, 0, this.canvas.width - 100, this.canvas.height);204    }205    206    drawObstacle(obstacle) {207        this.ctx.fillStyle = obstacle.color;208        this.ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);209        210        // Add some details to the obstacle211        this.ctx.fillStyle = '#000000';212        this.ctx.fillRect(obstacle.x + 5, obstacle.y + 5, obstacle.width - 10, obstacle.height - 10);213    }214    215    drawCar() {216        // Car body217        this.ctx.fillStyle = '#3b82f6';218        this.ctx.fillRect(this.car.x, this.car.y, this.car.width, this.car.height);219        220        // Car details221        this.ctx.fillStyle = '#ffffff';222        this.ctx.fillRect(this.car.x + 5, this.car.y + 10, this.car.width - 10, 20); // windshield223        this.ctx.fillRect(this.car.x + 5, this.car.y + this.car.height - 25, this.car.width - 10, 15); // bumper224        225        // Wheels226        this.ctx.fillStyle = '#000000';227        this.ctx.fillRect(this.car.x - 5, this.car.y + 10, 5, 20); // left wheel228        this.ctx.fillRect(this.car.x + this.car.width, this.car.y + 10, 5, 20); // right wheel229        this.ctx.fillRect(this.car.x - 5, this.car.y + this.car.height - 30, 5, 20); // left rear wheel230        this.ctx.fillRect(this.car.x + this.car.width, this.car.y + this.car.height - 30, 5, 20); // right rear wheel231    }232    233    updateDisplay() {234        document.getElementById('score').textContent = this.score;235        document.getElementById('timer').textContent = this.timer;236        document.getElementById('lives').textContent = this.lives;237    }238    239    gameOver() {240        this.gameActive = false;241        clearInterval(this.gameLoop);242        document.getElementById('finalScore').textContent = this.score;243        document.getElementById('gameOver').classList.remove('hidden');244    }245    246    restartGame() {247        this.score = 0;248        this.timer = 60;249        this.lives = 3;250        this.obstacles = [];251        this.frameCount = 0;252        this.car.x = this.canvas.width / 2 - 25;253        this.updateDisplay();254        document.getElementById('gameOver').classList.add('hidden');255        this.startGame();256    }257}258 259// Initialize game when page loads260document.addEventListener('DOMContentLoaded', () => {261    new RacingGame();262});