For my midterm, I had to create a game primarily focused on cats, driven by my love for them. The game’s objective is to reach a score of 20 by catching as many cats as possible within thirty seconds. Additionally, there is a power-up cat that boosts your score. I encountered two unsuccessful attempts in executing my ideas, leading me to start over, which I believe turned out quite well.
My initial idea was to create a game inspired by “My Talking Tom,” a game I enjoyed playing while growing up. I aimed to introduce a twist by replacing the cat with a camel. However, when it came time to execute the idea, I was unsure of how to begin and could not find any examples to follow.
My second idea involved creating an interactive game using PoseNet, modeled after the classic “I’ve got your nose” game. The core code functioned well; however, implementing the menu and other deliverables proved difficult, as they interfered with the rest of the code’s functionality. If you’re interested in trying it out, I recommend visiting the actual sketch, as you’ll need your webcam.
Moving on to the actual game, I aimed to create something simple and easy to play. However, I do wish it offered more of a challenge to players. Perhaps increasing the speed or adding another character that reduces the score instead of offering power-ups could enhance the difficulty. Additionally, feedback from one of my classmates highlighted the importance of clear instructions. Given the potential for confusion, providing explicit instructions regarding the timeframe, the scoring system, and the power-up cat would make it easier for users to understand and enjoy the game.
In terms of challenges, I faced issues similar to those of my classmates, particularly with the sketch not accepting images. I was advised to either work on the code locally or clear my cache to resolve this issue. However, my main challenges were related to the stylistic aspects of the game and deciphering the keyPressed(); function. Additionally, linking all parts of the game—from the menu to the game itself, and then to the win or lose screen—before looping it all back to the menu was probably the most time-consuming aspect of this entire project.
The most enjoyable aspect of this project for me was creating the graphics. I utilized Canva and Vecteezy to source all the elements needed to achieve the pixelated Mario aesthetic I desired.
Code + Notes:
// Midterm Project by Amal Almazrouei // Credit: // Sound: https://www.voicy.network/ // Font: Google Fonts // Images: https://www.vecteezy.com/ ; pinterest.com // Graphics: canva.com // Example Code: https://editor.p5js.org/simontiger/sketches/Dj7GS2035 // Flags to control game state let started = false; let gameEnded = true; // Treat game as ended initially to present start menu let showingEndScreen = false; // Indicates if end screen is currently displayed // Game timing and positioning variables let startTime; let x = 200; let y = 200; let powerX = 100; let powerY = 200; // Score and game dynamics variables let score = 0; let r = 48; // Radius for interactive elements let interval = 60; // Controls frequency of game events let frames = interval; // Countdown to trigger game events let powerIsThere = false; // Flag for power-up appearance let increase = 1; // Score increment let increased = 0; // Assets and sound variables let img, powerImg, startScreenBg; // Image variables for game elements let myFont; // Custom font variable let backgroundMusic, catSound, powerUpSound, winSound, loseSound; // Sound variables function preload() { // Preload all necessary media assets img = loadImage('Media/cat1.png'); // Main character image powerImg = loadImage('Media/cat2.png'); // Power-up image startScreenBg = loadImage('Media/startScreenBg.png'); // Start screen background image myFont = loadFont('assets/MyFont.ttf'); // Custom font // Loading sound assets backgroundMusic = loadSound('sounds/backgroundMusic.mp3'); catSound = loadSound('sounds/catSound.mp3'); powerUpSound = loadSound('sounds/powerUpSound.mp3'); winSound = loadSound('sounds/winSound.mp3'); loseSound = loadSound('sounds/loseSound.mp3'); } function setup() { createCanvas(400, 400); textFont(myFont); // Set the custom font backgroundMusic.loop(); // Play background music on loop } function keyPressed() { // Handles key presses for restarting or transitioning from end screen if (gameEnded && showingEndScreen) { showingEndScreen = false; // Exit end screen to show start menu } else if (!started && !showingEndScreen && gameEnded) { resetGame(); // Reset and start game from menu } } function resetGame() { // Reinitialize game variables for a new session started = true; gameEnded = false; showingEndScreen = false; startTime = millis(); // Reset game timing and positioning x = 200; y = 200; score = 0; r = 48; interval = 60; frames = interval; powerIsThere = false; increase = 1; increased = 0; clear(); // Clear the screen before starting } function mousePressed() { // Handle player interactions with game elements if (started && !gameEnded && !showingEndScreen) { if (dist(mouseX, mouseY, x, y) < r) { catSound.play(); // Random chance for score increase const rand = random(1); if (rand < 0.02) { increase = 50; } else if (rand < 0.1) { increase = 10; } else { increase = 1; } score += increase; increased = 20; interval--; r--; } if (powerIsThere && dist(mouseX, mouseY, powerX, powerY) < r) { powerUpSound.play(); score++; interval = 60; r = 48; powerIsThere = false; // Remove power-up after clicking } } } function draw() { // Main animation loop: Update game screen based on state if (!started && !showingEndScreen) { gameStartScreen(); // Show start screen if game hasn't started } else if (started && !gameEnded) { // Game play updates let currentMillis = millis(); background(135, 206, 235); // Set background // Display power-up image if present if (powerIsThere) { image(powerImg, powerX - r, powerY - r, r * 2, r * 2); } // Display main character image image(img, x - r, y - r, r * 2, r * 2); // Display score and time left textAlign(LEFT, TOP); textSize(30); fill(255, 0, 255); // Set text color text(score, 15, 15); let timeLeft = 30 - Math.floor((currentMillis - startTime) / 1000); text("Time: " + timeLeft, 15, 50); // Update positions and check for game end conditions frames--; if (frames <= 0) { frames = interval; x = random(width); y = random(height); if (random(1) < 0.07) { powerIsThere = true; powerX = random(width); powerY = random(height); } else { powerIsThere = false; } } if (score >= 20) { endGame(true); // Player won } else if (currentMillis - startTime > 30000) { endGame(false); // Time's up, player lost } } } function endGame(win) { // Handle game end: Show win or lose screen started = false; gameEnded = true; showingEndScreen = true; background(135, 206, 235); // Optionally reset background textAlign(CENTER, CENTER); textSize(32); // Display win or lose message if (win) { winSound.play(); fill(0, 0, 128); // Blue color for win text("You Win!", width / 2, height / 2); } else { loseSound.play(); fill(0, 0, 128); // Blue color for lose text("You Lose!", width / 2, height / 2); } fill(255, 0, 255); // Magenta color for subtitle textSize(24); // Smaller font size for subtitle text("Press any key to continue", width / 2, height / 2 + 20); } function gameStartScreen() { // Display start screen at game launch image(startScreenBg, 0, 0, 400, 400); }
Credit + Resources:
Sound: https://www.voicy.network/
Font: Google Fonts
Images: https://www.vecteezy.com/ ; pinterest.com
Graphics: canva.com
Example Code: https://editor.p5js.org/simontiger/sketches/Dj7GS2035