let ship; let asteroids = []; let pizzas = []; let hamburgers = []; let bullets = []; let shieldOrb = null; let greenOrb = null; let lives = 50; let score = 0; let gameOver = false; let lastShieldSpawn = 0; let lastGreenSpawn = 0; let pizzaImg, hamburgerImg; let level = 1; let initialObjects = 5; let kidMode = false; function preload() { pizzaImg = loadImage('pizza.png', () => console.log('Pizza image loaded'), () => console.error('Failed to load pizza.png')); hamburgerImg = loadImage('hamburger.png', () => console.log('Hamburger image loaded'), () => console.error('Failed to load hamburger.png')); } function setup() { createCanvas(800, 600, P2D, 'gameCanvas'); window.kidMode = kidMode; // Set global kidMode before spawning ship = new Ship(); spawnObjects(initialObjects); } function spawnObjects(numObjects) { for (let i = 0; i < numObjects; i++) { let rand = random(); if (rand < 0.15) { pizzas.push(new Pizza()); console.log(`Spawned pizza at level ${level}, total pizzas: ${pizzas.length}`); } else if (rand < 0.25) { asteroids.push(new Asteroid(null, null, true)); // Golden asteroid console.log(`Spawned golden asteroid at level ${level}, total asteroids: ${asteroids.length}`); } else { asteroids.push(new Asteroid(null, null, false)); // White asteroid console.log(`Spawned white asteroid at level ${level}, total asteroids: ${asteroids.length}`); } } } 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, score, level, and kid mode textSize(20); fill(255); text("Lives: " + lives, 50, 30); text("Score: " + score, 50, 60); text("Level: " + level, 50, 90); text("Kid Mode: " + (kidMode ? "ON" : "OFF"), 70, 120); // Handle continuous key input (WASD and Arrow Keys) if (keyIsDown(65) || keyIsDown(LEFT_ARROW)) { // A or Left Arrow ship.setRotation(-0.1); } if (keyIsDown(68) || keyIsDown(RIGHT_ARROW)) { // D or Right Arrow ship.setRotation(0.1); } if (keyIsDown(87) || keyIsDown(UP_ARROW)) { // W or Up Arrow 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(true); // Reset ship with safe spawn } } // 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 ? 50 : 10; // 50 points for golden, 10 for regular break; // Exit bullet loop after collision } } } // Update and show pizzas for (let i = pizzas.length - 1; i >= 0; i--) { if (!pizzas[i]) continue; // Skip if pizza is undefined pizzas[i].update(); pizzas[i].show(); pizzas[i].edges(); // Check collision with ship if (ship.hits(pizzas[i]) && !ship.shieldActive) { lives--; if (lives <= 0) { gameOver = true; } else { ship = new Ship(true); // Reset ship with safe spawn } } // Check collision with bullets for (let j = bullets.length - 1; j >= 0; j--) { if (pizzas[i] && pizzas[i].hits(bullets[j])) { let newHamburgers = pizzas[i].breakup(); pizzas.splice(i, 1); bullets.splice(j, 1); hamburgers.push(...newHamburgers); score += 20; // 20 points for pizza console.log(`Pizza destroyed, spawned ${newHamburgers.length} hamburgers, total hamburgers: ${hamburgers.length}`); break; // Exit bullet loop after collision } } } // Update and show hamburgers for (let i = hamburgers.length - 1; i >= 0; i--) { if (!hamburgers[i]) continue; // Skip if hamburger is undefined hamburgers[i].update(); hamburgers[i].show(); hamburgers[i].edges(); // Check collision with ship if (ship.hits(hamburgers[i]) && !ship.shieldActive) { lives--; if (lives <= 0) { gameOver = true; } else { ship = new Ship(true); // Reset ship with safe spawn } } // Check collision with bullets for (let j = bullets.length - 1; j >= 0; j--) { if (hamburgers[i] && hamburgers[i].hits(bullets[j])) { hamburgers.splice(i, 1); bullets.splice(j, 1); score += 10; // 10 points for hamburger console.log(`Hamburger destroyed, total hamburgers: ${hamburgers.length}`); break; // Exit bullet loop after collision } } } // Check for level completion if (asteroids.length === 0 && pizzas.length === 0 && hamburgers.length === 0 && !gameOver) { console.log(`Level ${level} completed! Asteroids: ${asteroids.length}, Pizzas: ${pizzas.length}, Hamburgers: ${hamburgers.length}`); level++; initialObjects = Math.ceil(initialObjects * 1.1); // Increase by 10% bullets = []; // Clear bullets ship = new Ship(true); // Reset ship with safe spawn spawnObjects(initialObjects); console.log(`Starting Level ${level} with ${initialObjects} objects`); } } function keyPressed() { if (keyCode === 32) { // Spacebar to shoot if (ship.quadShotActive) { // Fire in four directions: forward, backward, left, right gun_count = 4 shooting_fan_angle = Math.PI / 4.0 angle_between = shooting_fan_angle / gun_count for (let gun_index = 0; gun_index < gun_count; gun_index++) { gun_angle = gun_index * angle_between bullets.push(new Bullet(ship.pos, ship.heading + gun_angle - (shooting_fan_angle/2.0))); } } else { bullets.push(new Bullet(ship.pos, ship.heading)); } } if (keyCode === 82 && gameOver) { // R to restart lives = 3; score = 0; level = 1; initialObjects = 5; asteroids = []; pizzas = []; hamburgers = []; bullets = []; shieldOrb = null; greenOrb = null; ship = new Ship(true); // Safe spawn on restart lastShieldSpawn = millis(); lastGreenSpawn = millis(); spawnObjects(initialObjects); gameOver = false; } if (keyCode === 75) { // K to toggle Kid Mode kidMode = !kidMode; window.kidMode = kidMode; // Update global kidMode console.log(`Kid Mode: ${kidMode ? 'ON' : 'OFF'}`); } } function keyReleased() { if (keyCode === 65 || keyCode === 68 || keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) { // A, D, Left, Right ship.setRotation(0); } if (keyCode === 87 || keyCode === UP_ARROW) { // W or Up Arrow ship.boosting(false); } }