let gameMode = 0; // Variable to store the current game mode
let musicSound; // Variable to hold the music sound object
let gameoverSound; // Variable to hold the game over sound object
let scoreSound; // Variable to hold the score sound object
var landscape; // Variable to store the landscape graphics
var car_diameter = 15; // Diameter of the ball
var bomb_diameter = 10; // Diameter of the bombs
var zapperwidth = 6; // Width of the zapper
var numofbombs = 10; // Number of bombs
var bombposX = []; // Array to store X positions of bombs
var bombposY = []; // Array to store Y positions of bombs
var bombacceleration = []; // Array to store acceleration of each bomb
var bombvelocity = []; // Array to store velocity of each bomb
var time = 0; // Variable to track time, usage context not provided
var timeperiod = 0; // Variable to store a time period, usage not clear without further context
var score = 0; // Variable to store the current score
var posX; // X position, usage context not provided
var inMainMenu = true; // Boolean to check if the game is in the main menu
var prevScore = 0; // Variable to store the previous score
let font; // Variable to store font, usage context not provided
let oneDimensionarray = [];
spritesheet = loadImage("clouds.png");
musicSound = loadSound("sounds/song.mp3");
gameoverSound = loadSound("sounds/gameover.mp3");
scoreSound = loadSound("sounds/score.mp3");
glassbreak = loadSound("sounds/glassbreaking.wav");
font = loadFont("fonts/Inconsolata_Condensed-Light.ttf");
car = loadImage("car.png");
car2 = loadImage("car2.png");
constructor(x, y, speed, stepSpeed, scale) {
this.scale = scale; // Add scale property
this.stepSpeed = stepSpeed;
this.facingRight = false; // Initially moving to the left
this.animationTimer = null;
if (this.x > width + spritesheet.width / 4) {
this.x = -spritesheet.width / 4; // Wrap around to the left side
if (this.x < -spritesheet.width / 4) {
this.x = width + spritesheet.width / 4; // Wrap around to the right side
scale(-this.scale, this.scale); // Apply scale with horizontal flip
image(oneDimensionarray[this.step], -this.x, this.y);
scale(this.scale, this.scale); // Apply scale
image(oneDimensionarray[this.step], this.x, this.y);
this.step = (this.step + 1) % 8;
clearInterval(this.animationTimer);
this.animationTimer = setInterval(() => this.advanceStep(), this.stepSpeed);
this.facingRight = false;
clearInterval(this.animationTimer);
// A while loop that increments temp01 based on temp00 until temp01 is less than the canvas height
while (temp01 < height) {
temp00 += 0.02; // Increment temp00 by 0.02 in each loop iteration
temp01 += temp00; // Increment temp01 by the current value of temp00
timeperiod++; // Increment timeperiod in each iteration
// Calculate the initial position of posX based on zapperwidth and car_diameter
posX = zapperwidth + 0.5 * car_diameter - 2;
// Set xpoint and ypoint relative to the width and height of the canvas
xpoint = 0.7 * width; // Set xpoint to 70% of the canvas width
ypoint = height - 0.5 * car_diameter + 1; // Set ypoint based on the canvas height and car_diameter
initbombpos(); // Call the initbombpos function (presumably initializes bomb positions)
imageMode(CENTER); // Set the image mode to CENTER for drawing images centered at coordinates
// Initialize variables for width and height based on sprite sheet dimensions divided by specific values
let w = spritesheet.width / 2;
let h = spritesheet.height / 4;
// Nested for loops to extract sprite images from the sprite sheet and push them to oneDimensionarray
for (let y = 0; y < 4; y++) {
for (let x = 0; x < 2; x++) {
oneDimensionarray.push(spritesheet.get(x * w, y * h, w, h)); // Get sub-images from spritesheet and add to oneDimensionarray
// Create 3 clouds with horizontal offsets, different speeds and scales
clouds.push(new Cloud(width / 8, height / 9, 0, 100, 0.9)); // First cloud
clouds.push(new Cloud((2 * width) / 5, height / 9, 0, 100, 1.2)); // Second cloud
clouds.push(new Cloud((2 * width) / 2, height / 9, 0, 200, 1.0)); // Third cloud
clouds.forEach((cloud) => {
textSize(50); // Larger text size for the game title
textAlign(CENTER, CENTER); // Align text to be centered
text('HAILSTORM HAVOC', width / 2, height / 2 - 40);
textSize(16); // Smaller text size for the directions
// Draw the directions right below the game title
text('DIRECTIONS:\n click mouse to dodge hail\n the longer the press the further right\n the car will go\n\n AVOID the red line - crossing it means game over', width / 2, (height / 2) + 50);
text('Click to start!', width / 2, (height / 2) + 140);
else if (gameMode == 1) {
clouds.forEach((cloud) => {
rect(0, 0, zapperwidth, height);
for (var i = 0; i < numofbombs; i++) {
ellipse(bombposX[i], bombposY[i], bomb_diameter, bomb_diameter);
// ellipse(xpoint, ypoint, car_diameter, car_diameter);
image(car,xpoint, ypoint-30, car_diameter*5, car_diameter*5);
// Check if the mouse is pressed and the xpoint is within the canvas boundaries
if (mouseIsPressed && xpoint + 0.5 * car_diameter < width) {
xpoint += 6; // Move the xpoint to the right by 6 units
// Check if xpoint is less than or equal to posX or if a collision with a bomb has occurred
if (xpoint <= posX || bombCollistonTest()) {
gameover(); // Call the gameover function if either condition is true
// Increment the score every 60 frames
if (frameCount % 60 == 0) {
score++; // Increase score by 1
function updatebombpos() {
// Iterate over each bomb
for (var i = 0; i < numofbombs; i++) {
bombvelocity[i] += bombacceleration[i]; // Update the velocity of the bomb by adding its acceleration
bombposY[i] += bombvelocity[i]; // Update the Y position of the bomb based on its velocity
initbombpos(); // Reinitialize the positions of the bombs by calling the initbombpos function
for (var i = 0; i < numofbombs; i++) {
bombacceleration[i] = random(0.02, 0.03);
bombvelocity[i] = random(0, 5);
bombposX[i] = random(zapperwidth + 0.5 * car_diameter, width);
bombposY[i] = random(-20, -0.5 * car_diameter) + 190;
} //This function initializes the position and motion properties of each bomb by assigning random values within specified ranges.
function bombCollistonTest() {
var temp = 0.5 * (car_diameter + bomb_diameter) - 2;
// Iterate over each bomb to check for a collision
for (var i = 0; i < numofbombs; i++) {
distance = dist(xpoint, ypoint, bombposX[i], bombposY[i]);
} //This function checks for collisions between the player and each bomb by comparing the distance between them to a threshold. If any bomb is too close (within the threshold), it returns true (collision detected). Otherwise, it returns false.
image(car2,xpoint, ypoint-30, car_diameter*5, car_diameter*5);
textSize(50); // Set the text size
textAlign(CENTER, CENTER); // Align text to the center
text("GAME OVER", width / 2, height / 2 - 20); // Center the text horizontally and vertically
textSize(15); // Decreased text size for "press space to restart" text
text("Press space to restart", width / 2, height / 2 + 20); // Positioned below "GAME OVER" text
if (score != prevScore) //// Play the scoring sound only if the current score has changed from the previous score
fill(128, 128, 128, 150);
rect(width - 100, 5, 75, 20, 5);
text("SCORE: " + int(score), width - 65, 15);
// Check if the key pressed is space (keyCode 32)
restartGame(); // Call the function to restart the game
function mousePressed() {
console.log("Mouse Press");
//just flipping between modes 0 and 1
clouds.forEach((cloud) => cloud.startAnimation());
function mouseReleased() {
clouds.forEach((cloud) => cloud.stopAnimation());
// Reset all game variables to their initial values
posX = zapperwidth + 0.5 * car_diameter - 2;
ypoint = height - 0.5 * car_diameter + 1;
//This function resets the game environment and variables to their initial state, essentially restarting the game. It resumes background music, pauses any game over sound, resets score and time, repositions the player and bombs, and restarts the game loop.
let gameMode = 0; // Variable to store the current game mode
let musicSound; // Variable to hold the music sound object
let gameoverSound; // Variable to hold the game over sound object
let scoreSound; // Variable to hold the score sound object
var landscape; // Variable to store the landscape graphics
var car_diameter = 15; // Diameter of the ball
var bomb_diameter = 10; // Diameter of the bombs
var xpoint;
var ypoint;
var zapperwidth = 6; // Width of the zapper
var numofbombs = 10; // Number of bombs
var bombposX = []; // Array to store X positions of bombs
var bombposY = []; // Array to store Y positions of bombs
var bombacceleration = []; // Array to store acceleration of each bomb
var bombvelocity = []; // Array to store velocity of each bomb
var time = 0; // Variable to track time, usage context not provided
var timeperiod = 0; // Variable to store a time period, usage not clear without further context
var score = 0; // Variable to store the current score
var posX; // X position, usage context not provided
var inMainMenu = true; // Boolean to check if the game is in the main menu
var prevScore = 0; // Variable to store the previous score
let font; // Variable to store font, usage context not provided
//Cloud Variables
let spritesheet;
let oneDimensionarray = [];
function preload() {
spritesheet = loadImage("clouds.png");
musicSound = loadSound("sounds/song.mp3");
gameoverSound = loadSound("sounds/gameover.mp3");
scoreSound = loadSound("sounds/score.mp3");
glassbreak = loadSound("sounds/glassbreaking.wav");
font = loadFont("fonts/Inconsolata_Condensed-Light.ttf");
car = loadImage("car.png");
car2 = loadImage("car2.png");
}
// Cloud class starts
class Cloud {
constructor(x, y, speed, stepSpeed, scale) {
this.x = x;
this.y = y;
this.scale = scale; // Add scale property
this.speed = speed;
this.stepSpeed = stepSpeed;
this.step = 0;
this.facingRight = false; // Initially moving to the left
this.animationTimer = null;
}
move() {
if (this.facingRight) {
this.x += this.speed;
if (this.x > width + spritesheet.width / 4) {
this.x = -spritesheet.width / 4; // Wrap around to the left side
}
} else {
this.x -= this.speed;
if (this.x < -spritesheet.width / 4) {
this.x = width + spritesheet.width / 4; // Wrap around to the right side
}
}
}
display() {
push();
if (!this.facingRight) {
scale(-this.scale, this.scale); // Apply scale with horizontal flip
image(oneDimensionarray[this.step], -this.x, this.y);
} else {
scale(this.scale, this.scale); // Apply scale
image(oneDimensionarray[this.step], this.x, this.y);
}
pop();
}
advanceStep() {
this.step = (this.step + 1) % 8;
}
startAnimation() {
this.facingRight = true;
clearInterval(this.animationTimer);
this.animationTimer = setInterval(() => this.advanceStep(), this.stepSpeed);
}
stopAnimation() {
this.facingRight = false;
clearInterval(this.animationTimer);
}
}
let clouds = [];
// Cloud class ends
function setup() {
createCanvas(640, 480);
textAlign(CENTER);
musicSound.play();
var temp00 = 0,
temp01 = -20;
// A while loop that increments temp01 based on temp00 until temp01 is less than the canvas height
while (temp01 < height) {
temp00 += 0.02; // Increment temp00 by 0.02 in each loop iteration
temp01 += temp00; // Increment temp01 by the current value of temp00
timeperiod++; // Increment timeperiod in each iteration
}
// Calculate the initial position of posX based on zapperwidth and car_diameter
posX = zapperwidth + 0.5 * car_diameter - 2;
// Set xpoint and ypoint relative to the width and height of the canvas
xpoint = 0.7 * width; // Set xpoint to 70% of the canvas width
ypoint = height - 0.5 * car_diameter + 1; // Set ypoint based on the canvas height and car_diameter
initbombpos(); // Call the initbombpos function (presumably initializes bomb positions)
imageMode(CENTER); // Set the image mode to CENTER for drawing images centered at coordinates
// Initialize variables for width and height based on sprite sheet dimensions divided by specific values
let w = spritesheet.width / 2;
let h = spritesheet.height / 4;
// Nested for loops to extract sprite images from the sprite sheet and push them to oneDimensionarray
for (let y = 0; y < 4; y++) {
for (let x = 0; x < 2; x++) {
oneDimensionarray.push(spritesheet.get(x * w, y * h, w, h)); // Get sub-images from spritesheet and add to oneDimensionarray
}
}
// Create 3 clouds with horizontal offsets, different speeds and scales
clouds.push(new Cloud(width / 8, height / 9, 0, 100, 0.9)); // First cloud
clouds.push(new Cloud((2 * width) / 5, height / 9, 0, 100, 1.2)); // Second cloud
clouds.push(new Cloud((2 * width) / 2, height / 9, 0, 200, 1.0)); // Third cloud
}
function draw() {
background(58, 66, 94);
if (gameMode == 0) {
clouds.forEach((cloud) => {
cloud.display();
});
textFont(font);
fill(255);
textSize(50); // Larger text size for the game title
textAlign(CENTER, CENTER); // Align text to be centered
text('HAILSTORM HAVOC', width / 2, height / 2 - 40);
textSize(16); // Smaller text size for the directions
// Draw the directions right below the game title
text('DIRECTIONS:\n click mouse to dodge hail\n the longer the press the further right\n the car will go\n\n AVOID the red line - crossing it means game over', width / 2, (height / 2) + 50);
textSize(20);
text('Click to start!', width / 2, (height / 2) + 140);
}
else if (gameMode == 1) {
clouds.forEach((cloud) => {
cloud.move();
cloud.display();
});
fill(239, 58, 38);
rect(0, 0, zapperwidth, height);
scoreUpdate();
fill(255);
noStroke();
for (var i = 0; i < numofbombs; i++) {
ellipse(bombposX[i], bombposY[i], bomb_diameter, bomb_diameter);
}
updatebombpos();
// ellipse(xpoint, ypoint, car_diameter, car_diameter);
image(car,xpoint, ypoint-30, car_diameter*5, car_diameter*5);
xpoint -= 3;
// Check if the mouse is pressed and the xpoint is within the canvas boundaries
if (mouseIsPressed && xpoint + 0.5 * car_diameter < width) {
xpoint += 6; // Move the xpoint to the right by 6 units
}
// Check if xpoint is less than or equal to posX or if a collision with a bomb has occurred
if (xpoint <= posX || bombCollistonTest()) {
gameover(); // Call the gameover function if either condition is true
}
// Increment the score every 60 frames
time += 1;
if (frameCount % 60 == 0) {
score++; // Increase score by 1
}
}
}
function updatebombpos() {
// Iterate over each bomb
for (var i = 0; i < numofbombs; i++) {
bombvelocity[i] += bombacceleration[i]; // Update the velocity of the bomb by adding its acceleration
bombposY[i] += bombvelocity[i]; // Update the Y position of the bomb based on its velocity
}
if (time > timeperiod) {
initbombpos(); // Reinitialize the positions of the bombs by calling the initbombpos function
time = 0;
}
}
function initbombpos() {
for (var i = 0; i < numofbombs; i++) {
bombacceleration[i] = random(0.02, 0.03);
bombvelocity[i] = random(0, 5);
bombposX[i] = random(zapperwidth + 0.5 * car_diameter, width);
bombposY[i] = random(-20, -0.5 * car_diameter) + 190;
}
} //This function initializes the position and motion properties of each bomb by assigning random values within specified ranges.
function bombCollistonTest() {
var temp = 0.5 * (car_diameter + bomb_diameter) - 2;
var distance;
// Iterate over each bomb to check for a collision
for (var i = 0; i < numofbombs; i++) {
distance = dist(xpoint, ypoint, bombposX[i], bombposY[i]);
if (distance < temp) {
return true;
}
}
return false;
} //This function checks for collisions between the player and each bomb by comparing the distance between them to a threshold. If any bomb is too close (within the threshold), it returns true (collision detected). Otherwise, it returns false.
function gameover() {
image(car2,xpoint, ypoint-30, car_diameter*5, car_diameter*5);
musicSound.pause();
glassbreak.play();
gameoverSound.play();
textFont(font);
fill(255);
textSize(50); // Set the text size
textAlign(CENTER, CENTER); // Align text to the center
text("GAME OVER", width / 2, height / 2 - 20); // Center the text horizontally and vertically
textSize(15); // Decreased text size for "press space to restart" text
text("Press space to restart", width / 2, height / 2 + 20); // Positioned below "GAME OVER" text
noLoop();
}
function scoreUpdate() {
// score += 10;
if (score != prevScore) //// Play the scoring sound only if the current score has changed from the previous score
{
scoreSound.play();
}
prevScore = score;
fill(128, 128, 128, 150);
rect(width - 100, 5, 75, 20, 5);
fill(255);
text("SCORE: " + int(score), width - 65, 15);
}
function keyPressed() {
if (keyCode === 32) {
// Check if the key pressed is space (keyCode 32)
restartGame(); // Call the function to restart the game
}
}
function mousePressed() {
if (gameMode==0)
gameMode=1;
console.log("Mouse Press");
//just flipping between modes 0 and 1
clouds.forEach((cloud) => cloud.startAnimation());
}
function mouseReleased() {
clouds.forEach((cloud) => cloud.stopAnimation());
}
function restartGame() {
// Reset all game variables to their initial values
musicSound.play();
gameoverSound.pause();
time = 0;
score = 0;
posX = zapperwidth + 0.5 * car_diameter - 2;
xpoint = 0.5 * width;
ypoint = height - 0.5 * car_diameter + 1;
initbombpos();
// Restart the game loop
loop();
}
//This function resets the game environment and variables to their initial state, essentially restarting the game. It resumes background music, pauses any game over sound, resets score and time, repositions the player and bombs, and restarts the game loop.