xxxxxxxxxx
438
let imgRedApple, imgRottenApple, imgTrashCan, imgIntro, imgInstructions; // Variables for images
let trashCan; // Variable for the trashcan object
let apples = [], redApplesCollected = 0, score = 0, gameTimer = 60; // Arrays and variables for apples, score, and timer
let currentPage = 'intro'; // Variable to sound
let inputName; // Variable for the players name input
let bubbles = []; // Array for bubbles in game over screen
let introSound; // Variable for the intro sound
function preload() {
imgRedApple = loadImage('red.png');
imgRottenApple = loadImage('rotten.png');
imgTrashCan = loadImage('trash1.png');
imgIntro = loadImage('intro.jpeg');
imgInstructions = loadImage('Instruction.jpeg');
introSound = loadSound('sound.mp3');
}
function setup() {
createCanvas(windowWidth, windowHeight);
// Instantiate a new TrashCan object
trashCan = new TrashCan();
// Set default text size
textSize(32);
// Create an input field for players name
inputName = createInput('');
// Position of input field
inputName.position(150, height / 2 + 100);
// Hide the input field initially
inputName.hide();
}
function draw() {
// Clear canvas at beginning of each draw call
clear();
// Switch between game states/pages
switch (currentPage) {
case 'intro':
// Play intro sound if not already playing
if (!introSound.isPlaying()) {
introSound.play();
}
// Function to display intro page contents
displayIntro();
break;
case 'instructions':
// Stop intro sound when instructions are displayed
if (introSound.isPlaying()) {
introSound.stop();
}
// Function to display instructions page contents
displayInstructions();
break;
case 'game':
// Ensure intro sound is stopped when game starts
if (introSound.isPlaying()) {
introSound.stop();
}
// Function to handle game logic and rendering
runGame();
break;
case 'gameOver':
// Ensure intro sound is stopped on game over
if (introSound.isPlaying()) {
introSound.stop();
}
// Function to display game over page contents
displayGameOver();
break;
}
}
function displayIntro() {
image(imgIntro, 0, 0, width, height);
// Red for text
fill(255, 0, 0);
// White stroke for text
stroke(255);
strokeWeight(2);
textSize(60);
// Make the text bold
textStyle(BOLD);
//Align the text in middle of screen
textAlign(CENTER, CENTER);
text('Rotten Rescue', width / 2, height / 2 - 150);
// White for button
fill(255);
// Red outline for button
stroke(255, 0, 0);
strokeWeight(2);
rect(width / 2 - 60, height / 2 - 30, 120, 60, 20);
// Reset stroke to default for text
noStroke();
// Red for button text
fill(255, 0, 0);
// Adjust text size for 'Start' to fit button
textSize(24);
// Ensure 'Start' text is centered in button
text('Start', width / 2, height / 2);
}
function displayInstructions() {
image(imgInstructions, 0, 0, width, height);
// Black for text
fill(0);
// Set text size
textSize(20);
// Align text to the top left corner
textAlign(LEFT, TOP);
let textMargin = 30;
text('- Try to catch the rotten apples in the trash can within a 60 second period\nand avoid catching more than 2 normal apples or you LOSE!\n- Please write your name before starting the game',
// Text block aligned with margins
textMargin, height / 4, width - 2 * textMargin, height);
// Show input box on instructions page
inputName.show();
// Center input field
inputName.position(width / 2 - inputName.width / 2, height / 2 + 20);
// 'Next' button
// White for button
fill(255);
// Red outline
stroke(255, 0, 0);
strokeWeight(2);
// Draw 'Next' button
rect(width / 2 - 50, height / 2 + 100, 100, 50, 20);
// No stroke for text
noStroke();
// Red for button text
fill(255, 0, 0);
// Text size for button label
textSize(20);
// Center text for button
textAlign(CENTER, CENTER);
// Draw 'Next' button text
text('Next', width / 2, height / 2 + 125);
}
function runGame() {
inputName.hide();
// Set Instruction.jpeg as the background
image(imgInstructions, 0, 0, width, height);
trashCan.display();
trashCan.move();
// Displays score and timer at the top left
displayScore();
// Logic for apples falling and being collected or missed
if (frameCount % 60 === 0) {
let type = random(['clean', 'dirty']);
apples.push(new Apple(type));
}
for (let i = apples.length - 1; i >= 0; i--) {
apples[i].move();
apples[i].display();
if (apples[i].y + apples[i].size > trashCan.y && apples[i].x > trashCan.x && apples[i].x < trashCan.x + trashCan.width) {
if (apples[i].type === 'dirty') {
score += 10;
} else {
redApplesCollected++;
if (redApplesCollected >= 3) {
currentPage = 'gameOver';
// Create bubbles for game over animation
createBubbles(20);
break;
}
}
// Remove collected or missed apple from array
apples.splice(i, 1);
} else if (apples[i].y > height) {
// Remove apple that falls off screen
apples.splice(i, 1);
}
}
// Timer countdown and check for game over condition
if (frameCount % 60 === 0 && gameTimer > 0) {
gameTimer--;
} else if (gameTimer === 0) {
currentPage = 'gameOver'; // Time's up
createBubbles(20); // Prepare game over screen
}
// Drawing and positioning Start Over and Back buttons
drawGameButtons();
}
function displayScore() {
fill(0);
textAlign(LEFT, TOP);
textSize(20);
// Score display at top left
text(`Score: ${score}`, 10, 10);
// Timer display below score
text(`Time: ${gameTimer}`, 10, 30);
}
function drawGameButtons() {
// Start Over Button
// White background
fill(255);
// Black border
stroke(0);
// Positioned on top right
rect(width - 220, 10, 100, 40);
// Black text
fill(0);
noStroke();
textSize(16);
textAlign(CENTER, CENTER);
text('Start Over', width - 170, 30);
// Back Button
// White background
fill(255);
// Black border
stroke(0);
// Positioned next to Start Over button
rect(width - 100, 10, 100, 40);
// Black text
fill(0);
noStroke();
textSize(16);
text('Back', width - 50, 30);
}
function mouseClicked() {
// Start Over button logic
if (mouseX > width - 220 && mouseX < width - 120 && mouseY > 10 && mouseY < 50) {
resetGame();
}
// Back button logic
else if (mouseX > width - 100 && mouseX < width && mouseY > 10 && mouseY < 50) {
currentPage = 'intro';
}
}
function resetGame() {
// Reset timer to 60 seconds for a new game
gameTimer = 60;
//Reset score
score = 0;
// Reset red apples collected count
redApplesCollected = 0;
// Clear apples array
apples = [];
// Set current page back to game to restart
currentPage = 'game';
}
function drawGameButtons() {
// Start Over Button
// White background for button
fill(255);
// Black border
stroke(0);
// Positioned on the top right
rect(width - 220, 10, 100, 40);
fill(0); // Black text
noStroke();
textSize(16);
textAlign(CENTER, CENTER);
text('Start Over', width - 170, 30);
// Back Button
// White background for button
fill(255);
// Black border
stroke(0);
// Positioned on the top right, next to Start Over
rect(width - 110, 10, 100, 40);
// Black text
fill(0);
noStroke();
text('Back', width - 60, 30);
}
function displayGameOver() {
background(0);
bubbles.forEach(bubble => {
bubble.move();
bubble.display();
});
fill(255);
textSize(32);
textAlign(CENTER, CENTER);
text('Game Over', width / 2, height / 2 - 20);
textSize(20);
text(`Score: ${score}`, width / 2, height / 2 + 20);
// Draw 'Back' button
fill(255); // White background for the button
stroke(0); // Black border
rect(width - 110, 10, 100, 40);
noStroke();
fill(0); // Black text
textSize(16);
textAlign(CENTER, CENTER);
// Center the text within the button
text('Back', width - 60, 30);
}
function displayScore() {
fill(0); // Black text for visibility
// Align text to top-left for consistent positioning
textAlign(LEFT, TOP);
// Reasonable text size for score and timer visibility
textSize(20);
text(`Score: ${score}`, 10, 10); // Top-left corner
text(`Time: ${gameTimer}`, 10, 35); // Directly below score
}
function mouseClicked() {
// Handling button clicks when on the 'game' page
if (currentPage === 'game') {
// Start Over button
if (mouseX > width - 220 && mouseX < width - 120 && mouseY > 10 && mouseY < 50) {
resetGame();
}
// Back button (takes user back to the intro page from the game page)
else if (mouseX > width - 110 && mouseX < width - 10 && mouseY > 10 && mouseY < 50) {
currentPage = 'intro';
}
}
if (currentPage === 'gameOver') {
// Check if the 'Back' button area is clicked
if (mouseX > width - 110 && mouseX < width - 10 && mouseY > 10 && mouseY < 50) {
// Change to the introduction page
currentPage = 'intro';
}
}
//next in intro
if (currentPage === 'intro' && mouseX > width / 2 - 60 && mouseX < width / 2 + 60 && mouseY > height / 2 - 30 && mouseY < height / 2 + 30) {
currentPage = 'instructions';
} else if (currentPage === 'instructions' && mouseX > width / 2 - 50 && mouseX < width / 2 + 50 && mouseY > height / 2 + 100 && mouseY < height / 2 + 150) {
currentPage = 'game';
// Optionally reset the game when starting from instructions
resetGame();
}
}
function resetGame() {
// Reset the game timer to 60 seconds
gameTimer = 60;
// Reset the player's score
score = 0;
// Reset the count of red apples collected
redApplesCollected = 0;
// Clear the array of apples
apples = [];
// Set the current page back to the game to restart
currentPage = 'game';
}
//bubbles in canvas like we did in class
function createBubbles(num) {
bubbles = [];
for (let i = 0; i < num; i++) {
bubbles.push(new Bubble());
}
}
class Bubble {
constructor() {
this.x = random(width);
this.y = random(height);
this.size = random(20, 50);
this.speed = {
x: random(-2, 2),
y: random(-2, 2)
};
}
move() {
this.x += this.speed.x;
this.y += this.speed.y;
if (this.x < 0 || this.x > width) {
this.speed.x *= -1;
}
if (this.y < 0 || this.y > height) {
this.speed.y *= -1;
}
}
display() {
fill(255, 0, 0, 127); // Semi-transparent red
noStroke();
ellipse(this.x, this.y, this.size);
}
}