let ship; let asteroids = []; let bullets = []; let shieldOrb = null; let greenOrb = null; let lives = 3; let score = 0; let gameOver = false; let lastShieldSpawn = 0; let lastGreenSpawn = 0; function setup() { createCanvas(800, 600); ship = new Ship(); for (let i = 0; i < 5; i++) { asteroids.push(new Asteroid()); } } function draw() { background(0); if (gameOver) { textSize(32); fill(255); textAlign(CENTER); text("Game Over! Score: " + score, width / 2, height / 2); text("Press R to Restart", width / 2, height / 2 + 40); return; } // Display lives and score textSize(20); fill(255); text("Lives: " + lives, 50, 30); text("Score: " + score, 50, 60); // Handle continuous key input (WASD) if (keyIsDown(65)) { // A key ship.setRotation(-0.1); } if (keyIsDown(68)) { // D key ship.setRotation(0.1); } if (keyIsDown(87)) { // W key ship.boosting(true); } else { ship.boosting(false); } // Update and show ship ship.update(); ship.show(); ship.edges(); // Spawn shield orb periodically if (millis() - lastShieldSpawn > 15000 && !shieldOrb) { shieldOrb = new ShieldOrb(); lastShieldSpawn = millis(); } // Spawn green orb periodically if (millis() - lastGreenSpawn > 20000 && !greenOrb) { greenOrb = new GreenOrb(); lastGreenSpawn = millis(); } // Update and show shield orb if (shieldOrb) { shieldOrb.update(); shieldOrb.show(); shieldOrb.edges(); if (ship.hits(shieldOrb)) { ship.activateShield(); shieldOrb = null; } } // Update and show green orb if (greenOrb) { greenOrb.update(); greenOrb.show(); greenOrb.edges(); if (ship.hits(greenOrb)) { ship.activateQuadShot(); greenOrb = null; } } // Update and show bullets for (let i = bullets.length - 1; i >= 0; i--) { bullets[i].update(); bullets[i].show(); if (bullets[i].offscreen()) { bullets.splice(i, 1); } } // Update and show asteroids for (let i = asteroids.length - 1; i >= 0; i--) { if (!asteroids[i]) continue; // Skip if asteroid is undefined asteroids[i].update(); asteroids[i].show(); asteroids[i].edges(); // Check collision with ship if (ship.hits(asteroids[i]) && !ship.shieldActive) { lives--; if (lives <= 0) { gameOver = true; } else { ship = new Ship(); // Reset ship position } } // Check collision with bullets for (let j = bullets.length - 1; j >= 0; j--) { if (asteroids[i] && asteroids[i].hits(bullets[j])) { let isGolden = asteroids[i].isGolden; // Store before removal let newAsteroids = asteroids[i].breakup(); asteroids.splice(i, 1); bullets.splice(j, 1); asteroids.push(...newAsteroids); score += isGolden ? 20 : 10; // Use stored isGolden value break; // Exit bullet loop after collision } } } } function keyPressed() { if (keyCode === 32) { // Spacebar to shoot if (ship.quadShotActive) { // Fire in four directions: forward, backward, left, right bullets.push(new Bullet(ship.pos, ship.heading)); bullets.push(new Bullet(ship.pos, ship.heading + PI)); bullets.push(new Bullet(ship.pos, ship.heading - PI / 2)); bullets.push(new Bullet(ship.pos, ship.heading + PI / 2)); } else { bullets.push(new Bullet(ship.pos, ship.heading)); } } if (keyCode === 82 && gameOver) { // R to restart lives = 3; score = 0; asteroids = []; bullets = []; shieldOrb = null; greenOrb = null; ship = new Ship(); lastShieldSpawn = millis(); lastGreenSpawn = millis(); for (let i = 0; i < 5; i++) { asteroids.push(new Asteroid()); } gameOver = false; } } function keyReleased() { if (keyCode === 65 || keyCode === 68) { // A or D key ship.setRotation(0); } if (keyCode === 87) { // W key ship.boosting(false); } }