xxxxxxxxxx
382
let ship;
let asteroids = [];
let bullets = [];
let score = 0;
let lives = 3;
let gameState = "start";
let turningLeft = false;
let turningRight = false;
let level = 1;
let bgImage; // Variable to hold background image
let shootSound; // Variable to hold shooting sound
let hitSound; // Variable to hold hit sound
let highScore = 0;
// Define constants
const SHIP_SIZE = 20;
const ASTEROID_SPEED = 2;
const BULLET_SPEED = 6;
const ASTEROID_COUNT = 5;
// Load assets in preload function
function preload() {
bgImage = loadImage("img1.jpg"); // Load background image
shootSound = loadSound("sound1.mp3"); // Load shooting sound
hitSound = loadSound("sound2.mp3"); // Load hit sound
}
function setup() {
createCanvas(windowWidth, windowHeight);
ship = new Ship();
for (let i = 0; i < ASTEROID_COUNT; i++) {
asteroids.push(new Asteroid());
}
}
function draw() {
background(0);
if (gameState === "start") {
background(bgImage);
displayStartScreen();
} else if (gameState === "play" || gameState === "levelComplete") {
// Include gameState "levelComplete"
ship.update();
ship.edges();
ship.display();
// Update and display asteroids
for (let asteroid of asteroids) {
asteroid.update();
asteroid.edges();
asteroid.display();
}
// Update and display bullets
for (let i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
bullets[i].display();
if (bullets[i].offscreen()) {
bullets.splice(i, 1);
} else {
// Check for collision with asteroids
for (let j = asteroids.length - 1; j >= 0; j--) {
if (bullets[i].hits(asteroids[j])) {
if (asteroids[j].r > 10) {
let newAsteroids = asteroids[j].breakup();
asteroids = asteroids.concat(newAsteroids);
}
hitSound.play();
asteroids.splice(j, 1);
bullets.splice(i, 1);
score += 10;
break;
}
}
}
}
// Display score and lives
textAlign(LEFT);
textSize(20);
fill(255);
text(`Score: ${score}`, 35, 30);
text(`Lives: ${lives}`, 35, 60);
// Check for collision with ship
for (let asteroid of asteroids) {
if (ship.hits(asteroid)) {
lives--;
if (lives <= 0) {
gameState = "gameover";
}
reset();
break;
}
}
// Check if all asteroids destroyed
if (asteroids.length === 0) {
levelComplete();
}
} else if (gameState === "gameover") {
displayGameOver();
}
}
// Function to handle key presses
function keyPressed() {
if (keyCode === UP_ARROW) {
ship.boosting(true);
} else if (keyCode === RIGHT_ARROW) {
turningRight = true;
} else if (keyCode === LEFT_ARROW) {
turningLeft = true;
} else if (key === " ") {
ship.shoot();
shootSound.play();
} else if (keyCode === ENTER && gameState === "start") {
gameState = "play";
} else if (keyCode === ENTER && gameState === "gameover") {
gameState = "play";
lives = 3;
level = 1;
score = 0;
}
if (keyCode === ESCAPE) {
let fs = fullscreen();
fullscreen(!fs);
}
}
// Function to handle key releases
function keyReleased() {
if (keyCode === UP_ARROW) {
ship.boosting(false);
} else if (keyCode === RIGHT_ARROW) {
turningRight = false;
} else if (keyCode === LEFT_ARROW) {
turningLeft = false;
}
ship.setRotation(0);
}
// Display start screen
function displayStartScreen() {
textSize(32);
fill(255);
textAlign(CENTER, CENTER);
textSize(20);
text("Controls:", width / 2, height / 2);
text("Up Arrow: Thrust", width / 2, height / 2 + 30);
text("Left/Right Arrows: Rotate", width / 2, height / 2 + 60);
text("Spacebar: Shoot", width / 2, height / 2 + 90);
text("Press ENTER to start", width / 2, height / 2 + 150);
}
// Display game over screen
function displayGameOver() {
background(bgImage);
textSize(32);
fill(255);
textAlign(CENTER, CENTER);
text("Game Over", width / 2, height / 2 - 15);
textSize(20);
text("Score: " + score, width / 2, height / 2 + 15);
highScore = (highScore < score) ? score : highScore;
text("High score: " + highScore, width / 2, height / 2 + 35);
text("Press ENTER to restart", width / 2, height / 2 + 65);
}
// Function to reset game
function reset() {
ship.pos = createVector(width / 2, height / 2);
ship.vel = createVector(0, 0);
ship.heading = PI / 2;
asteroids = [];
for (let i = 0; i < ASTEROID_COUNT; i++) {
asteroids.push(new Asteroid());
}
}
// Function to handle level complete
function levelComplete() {
score += 50; // Increase the player's score by 50
asteroids = []; // Clear existing asteroids
for (let i = 0; i < ASTEROID_COUNT + level; i++) {
// Increase the number of asteroids
asteroids.push(new Asteroid());
}
gameState = "levelComplete"; // Change the game state
setTimeout(() => {
// Display "Level Complete!" for 5 seconds
gameState = "play"; // Change the game state back to play
}, 5000);
}
// Spaceship class
class Ship {
constructor() {
this.pos = createVector(width / 2, height / 2);
this.vel = createVector(0, 0);
this.acc = createVector(0, 0);
this.heading = PI / 2;
this.rotation = 0;
this.isBoosting = false;
this.boost = createVector(0, 0);
this.maxSpeed = 4;
}
update() {
if (this.isBoosting) {
this.boosting(true);
}
this.pos.add(this.vel);
this.vel.add(this.acc);
this.vel.mult(0.99);
this.acc.mult(0);
if (turningRight) {
this.setRotation(0.05);
} else if (turningLeft) {
this.setRotation(-0.05);
}
}
boosting(b) {
this.isBoosting = b;
if (b) {
let force = p5.Vector.fromAngle(this.heading);
force.mult(0.1);
this.acc.add(force);
}
}
setRotation(a) {
this.heading += a;
}
edges() {
if (this.pos.x > width + SHIP_SIZE) {
this.pos.x = -SHIP_SIZE;
} else if (this.pos.x < -SHIP_SIZE) {
this.pos.x = width + SHIP_SIZE;
}
if (this.pos.y > height + SHIP_SIZE) {
this.pos.y = -SHIP_SIZE;
} else if (this.pos.y < -SHIP_SIZE) {
this.pos.y = height + SHIP_SIZE;
}
}
display() {
push();
translate(this.pos.x, this.pos.y);
rotate(this.heading + PI / 2);
fill(255);
stroke(255);
triangle(
-SHIP_SIZE / 2,
SHIP_SIZE / 2,
SHIP_SIZE / 2,
SHIP_SIZE / 2,
0,
-SHIP_SIZE / 2
);
pop();
}
shoot() {
let bullet = new Bullet(this.pos, this.heading);
bullets.push(bullet);
}
hits(asteroid) {
let d = dist(this.pos.x, this.pos.y, asteroid.pos.x, asteroid.pos.y);
if (d < asteroid.r + SHIP_SIZE / 2) {
return true;
} else {
return false;
}
}
}
// Asteroid class
class Asteroid {
constructor(pos, r) {
if (pos) {
this.pos = pos.copy();
} else {
this.pos = createVector(random(width), random(height));
}
this.vel = p5.Vector.random2D();
this.r = r || random(15, 50);
this.total = floor(random(10, 20));
this.offset = [];
for (let i = 0; i < this.total; i++) {
this.offset[i] = random(0, 15);
}
}
update() {
this.pos.add(this.vel);
}
edges() {
if (this.pos.x > width + this.r) {
this.pos.x = -this.r;
} else if (this.pos.x < -this.r) {
this.pos.x = width + this.r;
}
if (this.pos.y > height + this.r) {
this.pos.y = -this.r;
} else if (this.pos.y < -this.r) {
this.pos.y = height + this.r;
}
}
display() {
push();
translate(this.pos.x, this.pos.y);
noFill();
stroke(255);
beginShape();
for (let i = 0; i < this.total; i++) {
let angle = map(i, 0, this.total, 0, TWO_PI);
let r = this.r + this.offset[i];
let x = r * cos(angle);
let y = r * sin(angle);
vertex(x, y);
}
endShape(CLOSE);
pop();
}
breakup() {
let newAsteroids = [];
newAsteroids.push(new Asteroid(this.pos, this.r / 2));
newAsteroids.push(new Asteroid(this.pos, this.r / 2));
return newAsteroids;
}
}
// Bullet class
class Bullet {
constructor(pos, heading) {
this.pos = createVector(pos.x, pos.y);
this.vel = p5.Vector.fromAngle(heading);
this.vel.mult(BULLET_SPEED);
this.maxDist = 400;
this.startPos = pos.copy();
}
update() {
this.pos.add(this.vel);
}
display() {
push();
stroke(255);
strokeWeight(4);
point(this.pos.x, this.pos.y);
pop();
}
offscreen() {
if (
dist(this.pos.x, this.pos.y, this.startPos.x, this.startPos.y) >
this.maxDist
) {
return true;
}
return false;
}
hits(asteroid) {
let d = dist(this.pos.x, this.pos.y, asteroid.pos.x, asteroid.pos.y);
if (d < asteroid.r + 15) {
return true;
} else {
return false;
}
}
}