// Define variables for images, screens, sounds, buttons, game state, and other parameters
let bgImage, bgImage2, catImage, sharkImage, shellImage; // Images for background, cat, shark, and shell
let welcomeScreen, instructionScreen, countdownScreen, gameOverScreen; // Images for different game screens
let bgSound, collectedSound, sharkBiteSound; // Sound effects for background, collecting items, and shark bite
let replayButton, homeButton, pauseButton; // Buttons for replay, home, and pause (not implemented in the code)
let catY, sharks = [], shells = []; // Y position of the cat, arrays for sharks and shells
let bgX1 = 0, bgX2, speed = 4, hits = 0, score = 0; // Background positions, game speed, hit count, and score
let waterLevel; // Level of the water in the game
let gameState = 'welcome'; // Current state of the game (e.g., welcome, play, paused)
let countdownValue = 3; // Countdown value before the game starts
let accelerometerX, accelerometerY; // Variables to store accelerometer values (for physical device interaction)
let left = 50; // Value to be sent to Arduino
let right = -50; // Value to be sent to Arduino
// Preload function to load images and sounds before the game starts
bgImage = loadImage('background.png');
bgImage2 = loadImage('background2.png');
catImage = loadImage('cat.png');
sharkImage = loadImage('shark.png');
shellImage = loadImage('seashell.png');
welcomeScreen = loadImage('welcome screen.png');
instructionScreen = loadImage('instruction screen.png');
countdownScreen = loadImage('countdown screen.png');
gameOverScreen = loadImage('game over screen.png');
// Setup sound formats and load sound files
bgSound = loadSound('background sound.wav');
collectedSound = loadSound('collected.wav');
sharkBiteSound = loadSound('shark bite.wav');
// Function to read data from a serial connection (presumably from an Arduino)
function readSerial(data) {
// Check if the data is not null
let fromArduino = split(trim(data), ",");
if (fromArduino.length == 2) { // Ensure the data has two parts (X and Y)
accelerometerX = int(fromArduino[0]); // Parse X value
console.log(accelerometerX); // Log X value (for debugging)
accelerometerY = int(fromArduino[1]); // Parse Y value
console.log(accelerometerY); // Log Y value (for debugging)
let sendToArduino = left + "," + right + "\n"; // Prepare data to send back to Arduino
console.log('writing'); // Log writing action (for debugging)
writeSerial(sendToArduino); // Send data to Arduino (writeSerial function not provided in the code)
// Setup function runs once when the program starts
createCanvas(windowWidth, windowHeight); // Create a canvas that fills the window
catY = height / 2; // Set initial Y position of the cat
waterLevel = height / 2.5; // Set water level position
bgX2 = width; // Set initial position of the second background image
bgSound.loop(); // Play background sound in a loop
// Draw function continuously executes the lines of code contained inside its block
clear(); // Clear the canvas
displayScreenBasedOnState(); // Call function to display the appropriate screen based on the game state
// Function to display the current screen based on the game's state
function displayScreenBasedOnState() {
// Use a switch statement to handle different game states
image(welcomeScreen, 0, 0, width, height); // Display welcome screen
image(instructionScreen, 0, 0, width, height); // Display instructions screen
image(countdownScreen, 0, 0, width, height); // Display countdown screen
displayCountdown(); // Call function to display countdown
playGame(); // Call function to play the game
fill(173, 216, 230, 130); // Set color for pause screen overlay
rect(0, 0, width, height); // Draw rectangle overlay
fill(255); // Set color for text (white)
textSize(48); // Set text size
textAlign(CENTER, CENTER); // Set text alignment
text("Game Paused", width / 2, height / 2); // Display pause text
image(gameOverScreen, 0, 0, width, height); // Display game over screen
noLoop(); // Stop the draw loop, effectively pausing the game
// Function to display the countdown before the game starts
function displayCountdown() {
fill(255); // Set color for text (white)
textSize(70); // Set text size
textAlign(CENTER, CENTER); // Set text alignment
text(countdownValue, width / 2, height / 2); // Display countdown number
// Decrease countdown value every second
if (frameCount % 60 === 0 && countdownValue > 0) {
} else if (countdownValue === 0) {
gameState = 'play'; // Change game state to play when countdown reaches 0
countdownValue = 3; // Reset countdown value for next time
// Function to handle the gameplay
backgroundScrolling(); // Call function to scroll the background
displayCat(); // Call function to display the cat
handleSharks(); // Call function to handle sharks
handleSeashells(); // Call function to handle seashells
displayScore(); // Call function to display the score
increaseDifficulty(); // Call function to increase game difficulty over time
// Function to handle background scrolling
function backgroundScrolling() {
image(bgImage, bgX1, 0, width, height); // Draw the first background image
image(bgImage2, bgX2, 0, width, height); // Draw the second background image
bgX1 -= speed; // Move the first background image leftward
bgX2 -= speed; // Move the second background image leftward
// Reset background positions for continuous scrolling effect
if (bgX1 <= -width) bgX1 = bgX2 + width;
if (bgX2 <= -width) bgX2 = bgX1 + width;
// Function to display the cat character
// Move the cat up or down based on key presses or accelerometer data
if (keyIsDown(UP_ARROW) || keyIsDown(85)) catY -= 5; // Move up with UP_ARROW or 'U' key
if (keyIsDown(DOWN_ARROW) || keyIsDown(68)) catY += 5; // Move down with DOWN_ARROW or 'D' key
catY = accelerometerY + 500; // Position cat based on accelerometer data
catY = constrain(catY, waterLevel, height - 100); // Constrain cat's movement within the canvas
image(catImage, 50, catY, 125, 125); // Draw the cat image at the calculated position
// Function to handle sharks in the game
function handleSharks() {
// Generate new sharks at regular intervals
if (frameCount % 150 === 0) {
let sharkY = random(waterLevel - 1, height - 90); // Random Y position for sharks
sharks.push({ x: width, y: sharkY }); // Add new shark to the sharks array
// Loop through all sharks and update their positions
for (let i = sharks.length - 1; i >= 0; i--) {
shark.x -= speed; // Move shark leftward
image(sharkImage, shark.x, shark.y, 300, 300); // Draw shark image
// Check for collision between cat and shark
if (dist(30, catY, shark.x, shark.y) < 84) {
hits++; // Increase hits count
sharkBiteSound.play(); // Play shark bite sound
sharks.splice(i, 1); // Remove the collided shark from the array
gameState = 'gameOver'; // End the game after 3 hits
// Function to handle seashells in the game
function handleSeashells() {
// Generate new seashells at regular intervals
if (frameCount % 300 === 0) {
let shellY = random(waterLevel + 100, height - 70); // Random Y position for seashells
shells.push({ x: width, y: shellY }); }// Add new shell to the shells array
// Loop through all seashells and update their positions
for (let i = shells.length - 1; i >= 0; i--) {
shell.x -= speed; // Move shell leftward
image(shellImage, shell.x, shell.y, 50, 50); // Draw shell image
// Check for collision between cat and shell
if (dist(50, catY + 62.5, shell.x, shell.y) < 100) {
score++; // Increase score
shells.splice(i, 1); // Remove the collected shell from the array
collectedSound.play(); // Play sound upon collecting a shell
// Function to display the game score
function displayScore() {
fill(255); // Set text color to white
textSize(27); // Set text size
text('Score: ', 70, 30); // Display "Score: "
text(score, 150, 30); // Display the current score
image(shellImage, 110, 11, 30, 30); // Display shell icon next to score
text('Bitten: ', 70, 68); // Display "Bitten: "
text(hits, 150, 70); // Display the number of times the cat has been bitten
image(sharkImage, 73, 17, 100, 100); // Display shark icon next to hits
// Function to gradually increase the difficulty of the game
function increaseDifficulty() {
if (frameCount % 500 === 0) speed += 0.5; // Increase the speed of the game every 500 frames
// Function to toggle the game's pause state
if (gameState === 'play') {
gameState = 'paused'; // Change game state to paused
noLoop(); // Stop the draw loop, effectively pausing the game
} else if (gameState === 'paused') {
gameState = 'play'; // Resume playing the game
loop(); // Restart the draw loop
// Function that handles key press events
if (key === 'u') { // If 'u' is pressed, set up serial communication
setUpSerial(); // Function to set up serial communication (not provided in the code)
console.log('u clicked'); // Log action for debugging
else if (keyCode === 32) { // If space bar is pressed, toggle pause
} else if (keyCode === 82) { // If 'R' is pressed, reset the game
} else if (keyCode === 72) { // If 'H' is pressed, go to home screen
} else if (key === 'p' || key === 'P') { // If 'P' is pressed, proceed to the next game state
if (gameState === 'welcome') {
gameState = 'instructions';
} else if (gameState === 'instructions') {
// Function to reset the game to its initial state
sharks = []; // Clear the sharks array
shells = []; // Clear the shells array
score = 0; // Reset score to 0
hits = 0; // Reset hits to 0
catY = height / 2; // Reset the cat's position to the middle
gameState = 'countdown'; // Change the game state to countdown
countdownValue = 3; // Reset the countdown value
loop(); // Restart the draw loop
// Function to return to the game's home screen
sharks = []; // Clear the sharks array
shells = []; // Clear the shells array
score = 0; // Reset score to 0
hits = 0; // Reset hits to 0
catY = height / 2; // Reset the cat's position to the middle
gameState = 'welcome'; // Change the game state to welcome
countdownValue = 3; // Reset the countdown value
loop(); // Restart the draw loop
// Function to handle window resizing
function windowResized() {
resizeCanvas(windowWidth, windowHeight); // Resize the canvas to the new window size
// #include <SparkFun_MMA8452Q.h> // Include the SparkFun MMA8452Q accelerometer library
// MMA8452Q accel; // Create an instance of the MMA8452Q class
// Wire.begin(); // Initialize I2C communication
// if (accel.begin() == false) { // Initialize the accelerometer
// Serial.println("Not Connected. Please check connections and restart the sketch.");
// // Start the handshake
// while (Serial.available() <= 0) {
// Serial.println("0,0"); // Send a starting message to p5.js
// delay(300); // Wait for a bit
// // If there is data from p5.js, read it and blink the LED
// if (Serial.available()) {
// // Read the incoming data from p5.js
// int left = Serial.parseInt();
// int right = Serial.parseInt();
// // Read data from the accelerometer
// if (accel.available()) {
// accel.read(); // Read the accelerometer data
// int x = accel.getX(); // Get the X-axis data
// int y = accel.getY(); // Get the Y-axis data
// int z = accel.getZ(); // Get the Z-axis data
// // Send the accelerometer data to p5.js
// delay(100); // Delay before the next loop iteration
// Define variables for images, screens, sounds, buttons, game state, and other parameters
let bgImage, bgImage2, catImage, sharkImage, shellImage; // Images for background, cat, shark, and shell
let welcomeScreen, instructionScreen, countdownScreen, gameOverScreen; // Images for different game screens
let bgSound, collectedSound, sharkBiteSound; // Sound effects for background, collecting items, and shark bite
let replayButton, homeButton, pauseButton; // Buttons for replay, home, and pause (not implemented in the code)
let catY, sharks = [], shells = []; // Y position of the cat, arrays for sharks and shells
let bgX1 = 0, bgX2, speed = 4, hits = 0, score = 0; // Background positions, game speed, hit count, and score
let waterLevel; // Level of the water in the game
let gameState = 'welcome'; // Current state of the game (e.g., welcome, play, paused)
let countdownValue = 3; // Countdown value before the game starts
let accelerometerX, accelerometerY; // Variables to store accelerometer values (for physical device interaction)
let left = 50; // Value to be sent to Arduino
let right = -50; // Value to be sent to Arduino
// Preload function to load images and sounds before the game starts
function preload() {
// Load images
bgImage = loadImage('background.png');
bgImage2 = loadImage('background2.png');
catImage = loadImage('cat.png');
sharkImage = loadImage('shark.png');
shellImage = loadImage('seashell.png');
welcomeScreen = loadImage('welcome screen.png');
instructionScreen = loadImage('instruction screen.png');
countdownScreen = loadImage('countdown screen.png');
gameOverScreen = loadImage('game over screen.png');
// Setup sound formats and load sound files
soundFormats('wav');
bgSound = loadSound('background sound.wav');
collectedSound = loadSound('collected.wav');
sharkBiteSound = loadSound('shark bite.wav');
}
// Function to read data from a serial connection (presumably from an Arduino)
function readSerial(data) {
// Check if the data is not null
if (data != null) {
let fromArduino = split(trim(data), ",");
if (fromArduino.length == 2) { // Ensure the data has two parts (X and Y)
accelerometerX = int(fromArduino[0]); // Parse X value
console.log(accelerometerX); // Log X value (for debugging)
accelerometerY = int(fromArduino[1]); // Parse Y value
console.log(accelerometerY); // Log Y value (for debugging)
}
}
let sendToArduino = left + "," + right + "\n"; // Prepare data to send back to Arduino
console.log('writing'); // Log writing action (for debugging)
writeSerial(sendToArduino); // Send data to Arduino (writeSerial function not provided in the code)
}
// Setup function runs once when the program starts
function setup() {
createCanvas(windowWidth, windowHeight); // Create a canvas that fills the window
catY = height / 2; // Set initial Y position of the cat
waterLevel = height / 2.5; // Set water level position
bgX2 = width; // Set initial position of the second background image
bgSound.loop(); // Play background sound in a loop
}
// Draw function continuously executes the lines of code contained inside its block
function draw() {
clear(); // Clear the canvas
displayScreenBasedOnState(); // Call function to display the appropriate screen based on the game state
}
// Function to display the current screen based on the game's state
function displayScreenBasedOnState() {
// Use a switch statement to handle different game states
switch (gameState) {
case 'welcome':
image(welcomeScreen, 0, 0, width, height); // Display welcome screen
break;
case 'instructions':
image(instructionScreen, 0, 0, width, height); // Display instructions screen
break;
case 'countdown':
image(countdownScreen, 0, 0, width, height); // Display countdown screen
displayCountdown(); // Call function to display countdown
break;
case 'play':
playGame(); // Call function to play the game
break;
case 'paused':
fill(173, 216, 230, 130); // Set color for pause screen overlay
rect(0, 0, width, height); // Draw rectangle overlay
fill(255); // Set color for text (white)
textSize(48); // Set text size
textAlign(CENTER, CENTER); // Set text alignment
text("Game Paused", width / 2, height / 2); // Display pause text
break;
case 'gameOver':
image(gameOverScreen, 0, 0, width, height); // Display game over screen
noLoop(); // Stop the draw loop, effectively pausing the game
break;
}
}
// Function to display the countdown before the game starts
function displayCountdown() {
fill(255); // Set color for text (white)
textSize(70); // Set text size
textAlign(CENTER, CENTER); // Set text alignment
text(countdownValue, width / 2, height / 2); // Display countdown number
// Decrease countdown value every second
if (frameCount % 60 === 0 && countdownValue > 0) {
countdownValue--;
} else if (countdownValue === 0) {
gameState = 'play'; // Change game state to play when countdown reaches 0
countdownValue = 3; // Reset countdown value for next time
}
}
// Function to handle the gameplay
function playGame() {
backgroundScrolling(); // Call function to scroll the background
displayCat(); // Call function to display the cat
handleSharks(); // Call function to handle sharks
handleSeashells(); // Call function to handle seashells
displayScore(); // Call function to display the score
increaseDifficulty(); // Call function to increase game difficulty over time
}
// Function to handle background scrolling
function backgroundScrolling() {
image(bgImage, bgX1, 0, width, height); // Draw the first background image
image(bgImage2, bgX2, 0, width, height); // Draw the second background image
bgX1 -= speed; // Move the first background image leftward
bgX2 -= speed; // Move the second background image leftward
// Reset background positions for continuous scrolling effect
if (bgX1 <= -width) bgX1 = bgX2 + width;
if (bgX2 <= -width) bgX2 = bgX1 + width;
}
// Function to display the cat character
function displayCat() {
// Move the cat up or down based on key presses or accelerometer data
if (keyIsDown(UP_ARROW) || keyIsDown(85)) catY -= 5; // Move up with UP_ARROW or 'U' key
if (keyIsDown(DOWN_ARROW) || keyIsDown(68)) catY += 5; // Move down with DOWN_ARROW or 'D' key
catY = accelerometerY + 500; // Position cat based on accelerometer data
catY = constrain(catY, waterLevel, height - 100); // Constrain cat's movement within the canvas
image(catImage, 50, catY, 125, 125); // Draw the cat image at the calculated position
}
// Function to handle sharks in the game
function handleSharks() {
// Generate new sharks at regular intervals
if (frameCount % 150 === 0) {
let sharkY = random(waterLevel - 1, height - 90); // Random Y position for sharks
sharks.push({ x: width, y: sharkY }); // Add new shark to the sharks array
}
// Loop through all sharks and update their positions
for (let i = sharks.length - 1; i >= 0; i--) {
let shark = sharks[i];
shark.x -= speed; // Move shark leftward
image(sharkImage, shark.x, shark.y, 300, 300); // Draw shark image
// Check for collision between cat and shark
if (dist(30, catY, shark.x, shark.y) < 84) {
hits++; // Increase hits count
sharkBiteSound.play(); // Play shark bite sound
sharks.splice(i, 1); // Remove the collided shark from the array
if (hits >= 3) {
gameState = 'gameOver'; // End the game after 3 hits
}
}
}
}
// Function to handle seashells in the game
function handleSeashells() {
// Generate new seashells at regular intervals
if (frameCount % 300 === 0) {
let shellY = random(waterLevel + 100, height - 70); // Random Y position for seashells
shells.push({ x: width, y: shellY }); }// Add new shell to the shells array
// Loop through all seashells and update their positions
for (let i = shells.length - 1; i >= 0; i--) {
let shell = shells[i];
shell.x -= speed; // Move shell leftward
image(shellImage, shell.x, shell.y, 50, 50); // Draw shell image
// Check for collision between cat and shell
if (dist(50, catY + 62.5, shell.x, shell.y) < 100) {
score++; // Increase score
shells.splice(i, 1); // Remove the collected shell from the array
collectedSound.play(); // Play sound upon collecting a shell
}
}
}
// Function to display the game score
function displayScore() {
fill(255); // Set text color to white
textSize(27); // Set text size
text('Score: ', 70, 30); // Display "Score: "
text(score, 150, 30); // Display the current score
image(shellImage, 110, 11, 30, 30); // Display shell icon next to score
text('Bitten: ', 70, 68); // Display "Bitten: "
text(hits, 150, 70); // Display the number of times the cat has been bitten
image(sharkImage, 73, 17, 100, 100); // Display shark icon next to hits
}
// Function to gradually increase the difficulty of the game
function increaseDifficulty() {
if (frameCount % 500 === 0) speed += 0.5; // Increase the speed of the game every 500 frames
}
// Function to toggle the game's pause state
function togglePause() {
if (gameState === 'play') {
gameState = 'paused'; // Change game state to paused
noLoop(); // Stop the draw loop, effectively pausing the game
} else if (gameState === 'paused') {
gameState = 'play'; // Resume playing the game
loop(); // Restart the draw loop
}
}
// Function that handles key press events
function keyPressed() {
if (key === 'u') { // If 'u' is pressed, set up serial communication
setUpSerial(); // Function to set up serial communication (not provided in the code)
console.log('u clicked'); // Log action for debugging
}
else if (keyCode === 32) { // If space bar is pressed, toggle pause
togglePause();
} else if (keyCode === 82) { // If 'R' is pressed, reset the game
resetGame();
} else if (keyCode === 72) { // If 'H' is pressed, go to home screen
homeGame();
} else if (key === 'p' || key === 'P') { // If 'P' is pressed, proceed to the next game state
if (gameState === 'welcome') {
gameState = 'instructions';
} else if (gameState === 'instructions') {
gameState = 'countdown';
}
}
}
// Function to reset the game to its initial state
function resetGame() {
sharks = []; // Clear the sharks array
shells = []; // Clear the shells array
score = 0; // Reset score to 0
hits = 0; // Reset hits to 0
catY = height / 2; // Reset the cat's position to the middle
gameState = 'countdown'; // Change the game state to countdown
countdownValue = 3; // Reset the countdown value
loop(); // Restart the draw loop
}
// Function to return to the game's home screen
function homeGame() {
sharks = []; // Clear the sharks array
shells = []; // Clear the shells array
score = 0; // Reset score to 0
hits = 0; // Reset hits to 0
catY = height / 2; // Reset the cat's position to the middle
gameState = 'welcome'; // Change the game state to welcome
countdownValue = 3; // Reset the countdown value
loop(); // Restart the draw loop
}
// Function to handle window resizing
function windowResized() {
resizeCanvas(windowWidth, windowHeight); // Resize the canvas to the new window size
}
//ARDUINO CODE
// #include <Wire.h>
// #include <SparkFun_MMA8452Q.h> // Include the SparkFun MMA8452Q accelerometer library
// MMA8452Q accel; // Create an instance of the MMA8452Q class
// void setup() {
// Serial.begin(9600);
// Wire.begin(); // Initialize I2C communication
// if (accel.begin() == false) { // Initialize the accelerometer
// Serial.println("Not Connected. Please check connections and restart the sketch.");
// while (1);
// }
// // Start the handshake
// while (Serial.available() <= 0) {
// Serial.println("0,0"); // Send a starting message to p5.js
// delay(300); // Wait for a bit
// }
// }
// void loop() {
// // If there is data from p5.js, read it and blink the LED
// if (Serial.available()) {
// // Read the incoming data from p5.js
// int left = Serial.parseInt();
// int right = Serial.parseInt();
// }
// // Read data from the accelerometer
// if (accel.available()) {
// accel.read(); // Read the accelerometer data
// int x = accel.getX(); // Get the X-axis data
// int y = accel.getY(); // Get the Y-axis data
// int z = accel.getZ(); // Get the Z-axis data
// // Send the accelerometer data to p5.js
// Serial.print(x);
// Serial.print(",");
// Serial.println(y);
// }
// delay(100); // Delay before the next loop iteration
// }