Concept
For this week’s assignment, I decided to draw a bit from the skills I learned in Intro to CS back in my freshman year. I chose to implement a very simplified version of Pac-Man, something I always wanted to recreate.
Here is the final sketch (use the right arrow key to begin moving Pac-Man):
The idea is simple: you use the left and right arrow keys to move Pac-Man, and it eats the ghosts once it approaches them. Once all the ghosts are eaten, and Pac-Man returns to his starting position on the left side of the screen, the ghosts regenerate. This creates a sort of infinite loop.
Pac-Man:
The Pac-Man figure is created using the arc() function. On the p5 reference page for the function, there is a sample code for a biting Pac-Man. So, I used that in my assignment. I used Claude.ai to understand what each line of code was doing, specifically how the sin function works and how it enables the model to open and close its mouth. Building on this knowledge, I was able to adjust the speed at which Pac-Man was biting. I also added a boolean that checks if he is moving, so that he is only biting when he is moving.
Pac-Man’s movements are based on the pressing of the right and left arrow keys. From my Intro to CS class, where we built a sample Super Mario Bros game, I knew there must be a way to trigger movement when a specific key is pressed. With a Google search, I found that you can use
if (keyCode === LEFT_ARROW)
However, this function made it difficult to make Pac-Man move when the key is pressed and stop when the key is released. I had a bug where he would just keep moving on his own. I asked Claude.ai for a different function that is specifically for detecting if a key is held down or not, and it gave me the keyIsDown() function. This function returns true if the key is pressed, and false if not. This function fixed my bug and made Pac-Man stop and go correctly.
Ghosts:
For the ghosts, I found PNG images on Google and uploaded them to the sketch. Then, I found this sketch online, which includes a tutorial on how to load and display images.
I faced some difficulty with getting the ghosts to disappear when Pac-Man eats them. At first, I was just looping through the image names and displaying each image, then checking if the x position of Pac-Man and the image aligned, and deleting the image, but this was not doing anything. I asked Claude.ai why my code was not working, and it pointed out to me that images cannot hold x variables; therefore, I cannot check conditions using them. So, I created a simple Ghost class to store each ghost image’s x and y positions, its size, and image name. I made each ghost image an instance of the Ghost class, and stored them in a ghosts[] array. This allowed me to use the dist() function to see if Pac-Man was close to the ghost and delete that ghost instance from the array, which makes the ghost disappear from the sketch.
I was initially just going to leave the sketch with one iteration of displaying, then eating the ghosts, but then I decided to make it regenerate the ghosts every time they are all eaten. I did this by checking if the ghosts[] array is empty, because that indicates that all ghosts have been eaten. Adding only this condition gave me a small bug where the ghosts do not generate when the sketch first loads. It also would re-display the ghosts as soon as the last ghost is eaten, and since Pac-Man would be in proximity of the last and before last ghosts, it eats them immediately, making all the ghosts disappear as soon as they appear. Therefore, I added a condition that ensures that not only must the array be empty, but Pac-Man must also be on the left side of the screen (back at his starting position).
Code Snippet I am Proud of:
//loop backwards through the ghost objects to delete from the back of the array, otherwise you skip items in the array
for (let i = ghosts.length - 1; i >= 0; i--) {
let ghost = ghosts[i];
//display the ghost image
image(ghost.imgName, ghost.x, ghost.y, ghost.size, ghost.size);
//if the distance between the center of pacman and the center of the ghost is smaller than 50
if (dist(pacman.x, pacman.y, ghost.x + 40, ghost.y + 40) < 50) {
//delete that ghost object from the array so that it is not displayed
ghosts.splice(i, 1);
}
}
This is the code to display the ghost images and delete them when Pac-Man eats them. I am most proud of it because it took me the longest to figure out, and I made LOTS of edits until I reached the final version that worked.
Reflection
Overall, I am extremely happy with my work. Pac-Man has always been one of my favorite games, and I am thrilled I got the chance to recreate it. Despite running into a lot of bugs, they taught me a lot along the way, helped me discover new functions, and expanded my knowledge on how certain things are done in JavaScript since I have never coded using it before. For the future, I would definitely love to properly implement a full Pac-Man game, maybe for my final project 🙂
References
keyIsDown(): https://p5js.org/reference/p5/keyIsDown/
Image upload tutorial: https://editor.p5js.org/FAAH/sketches/8s1g0vilF
arc(): https://p5js.org/reference/p5/arc/
Claude AI: https://claude.ai/new
- Claude was used to understand the biting Pac-Man code from the arc() reference page, for debugging when the ghosts were not disappearing, and for finding the keyIsDown() function. It gave me the solution of creating a ghost class, which I then implemented on my own.