Concept
For this project, I’ve drawn inspiration from a childhood game my brother used to play, called the “Fishing game.” It involved catching fish with a fishing hook within a time limit. I’ve adapted this concept into my own version of the game, adding some twists and modifications. Instead of a traditional fishing game with a box of fish, my game features fish scattered randomly across the canvas. The objective remains the same: capture each fish individually using a fishing hook (the mouse) and deposit them into a fish bowl before time runs out. This adaptation allows for a unique gameplay experience while still capturing the essence of the original game.
Design
1. The game begins with an instructions page featuring a button labeled “Click here to continue” at the bottom.
2. Upon clicking, the player is directed to a page where they can select the number of fish to be displayed on the canvas, adjusting the game’s difficulty.
3. After choosing the level of difficulty, the player clicks a button labeled “Click here to start the game.”
4. Upon starting the game, a countdown timer begins, indicating the time limit for completing the game.
5. Background music plays throughout the game, creating an immersive experience.
6. If the player successfully captures all the fish before the timer runs out, they win the game.
7. Upon winning, a new page displays congratulating the player on their victory and showing their completion time.
8. A victory music plays to celebrate the player’s success.
9. If the player fails to capture all the fish before the timer expires, they lose the game.
10. Upon losing, a new page shows that the player has lost the game.
11. An end game music plays to signal the conclusion of the game.
Challenges with the project
1. Implementing the functionality to drag and drop each fish individually to the fish bowl has posed a significant challenge.
2. Creating an on-screen countdown timer that accurately tracks the remaining time and triggers the end game page when it reaches zero has been another obstacle.
3. Providing users with the ability to select their preferred difficulty level by choosing the number of fishes in the game initially proved to be problematic, requires for code refining.
4. Design challenge: Positioning the fish bowl on a table above water and making the users to drag the fish from the water surface into the bowl, which would make it aesthetically pleasing.
Code
let fishes = [];
let fishBowl;
let fishingHook;
let timer;
let gameStarted = false;
let gameFinished = false;
let numFishes = 5; // default number of fishes
function preload() {
fishBowl = loadImage('bowl.png'); // Load image for fish bowl
fishingHook = loadImage('hook.png'); // Load image for fishing hook
gameMusic = loadSound('gamemusic.mp3'); // Load background music
victoryMusic = loadSound('victorymusic.mp3'); // Load victory music
losingMusic = loadSound('losingmusic.mp3'); // Load losing music
}
function setup() {
createCanvas(800, 600);
timer = new Timer(numFishes); // timer object with the number of fishes
}
function draw() {
background("#2196F3");
if (!gameStarted) {
displayInstructions(); // Display instructions if game hasn't started
}
else {
timer.update(); // Update timer
if (!gameFinished) {
// Draw fish bowl
image(fishBowl, width / 2 - 50, height / 2 - 50, 150, 150);
// Draw fishing hook
image(fishingHook, mouseX - 25, mouseY - 25, 50, 50);
// Display and update fishes
for (let fish of fishes) { //checks each elements of the "fishes" array
fish.display();
//hooking the fishes to the hook
if (dist(mouseX, mouseY, fish.x, fish.y) < 25) {
fish.hooked = true;
}
if (fish.hooked) {
fish.move(mouseX, mouseY); //the fish is hooked to the hook
}
}
// Check if all fishes are inside fish bowl
let allFishesInside = true;
for (let fish of fishes) {
if (!fish.insideBowl) {
allFishesInside = false;
break;
}
}
if (allFishesInside) {
gameFinished = true;
timer.stop();
//play music
if (timer.timeLeft > 0) {
victoryMusic.play(); // Play victory music if game finished before countdown ends
gameMusic.stop(); // Stop background music
}
else {
losingMusic.play(); // Play losing music if countdown ends before game finished
gameMusic.stop(); // Stop background music
}
}
}
else {
fill(255)
textSize(40);
textAlign(CENTER, CENTER);
text("Game Over!", width / 2, height / 2);
text("Time left: " + timer.getTime() + " seconds", width / 2, height / 2 + 40);
}
}
}
function displayInstructions() {
// Display instructions
fill('rgb(0,0,134)'); //color of ellipse
ellipse(width/2, height/2,650,150); //ellispe in the center behind the circle
fill(255); //color of the texts
textSize(40); //size of texts
textAlign(CENTER, CENTER); //texts in the center of the canvas
text("Click to start the game", width / 2, height / 2);
}
function mousePressed() {
if (!gameStarted) { //if the game is not started
gameStarted = true; //the variable is set to true and it resets the fishes array
fishes = []; // Reset fishes array
//adding fishes to the canvas
for (let i = 0; i < numFishes; i++) {
fishes.push(new Fish(random(width), random(height)));
}
timer.start(); //countdown starts
gameMusic.loop(); // Play background music on loop
}
}
class Fish {
constructor(x, y) {
this.x = x;
this.y = y;
this.hooked = false;
this.insideBowl = false;
this.fishImage = loadImage('fish.png'); // Load fish image
}
display() {
image(this.fishImage, this.x - 25, this.y - 25, 50, 50); // Draw fish image
}
move(x, y) {
this.x = x;
this.y = y;
// Checking if the fish is inside the fish bowl
if (dist(x, y, width / 2, height / 2) < 50) {
this.insideBowl = true; // If the distance is less than 50, then the insideBowl property is set to true
}
}
}
class Timer {
constructor(numFishes) {
this.totalTime = numFishes * 1; // Adjust the total time based on the number of fishes
this.timeLeft = this.totalTime;
this.running = false;
}
start() {
this.startTime = millis();
this.running = true;
}
stop() {
this.endTime = millis();
this.running = false;
}
update() {
if (this.running) { //if the timer is running
let timePassed = millis() - this.startTime; //calculates the time passed since the timer started
this.timeLeft = max(0, this.totalTime - floor(timePassed / 1000)); // Calculate remaining time
if (this.timeLeft === 0) {
this.stop(); // Stop the timer when time runs out
}
}
}
getTime() {
return this.timeLeft;
}
}
Future Improvements and plans
1. Add more colors and deigns to the overall design of the game to make it more attractive, I want to make the design more aesthetically eye pleasing.
2. Add an instructions page to guide users on how to play the game.
3. Enable users to drag the fishes individually to the fish bowl for a more interactive experience.
4. I want to add more music to the game like subtle sounds and musics when the user interacts with the game.
5. Refine all aspects of the code to align with the initial plans and ensure smooth functionality.