NeoCade
- 5 Devlogs
- 17 Total hours
This is a simple web-based arcade where you can play classic games such as Pong, Snake, and Pacman directly in your browser.
This is a simple web-based arcade where you can play classic games such as Pong, Snake, and Pacman directly in your browser.
This session was about adding the third cgame to neocade. Originally i was going to add Asteroids but i changed my mind and added pacman instead. While building pacman, i initially just wanted to add an iframe to the original pacman game from somewhere but i hcanged my mind and wanted to build the entire thing myself. Here is what i buildt, how i build it, and the challenges i faced:
As i just said i built a pacman game which includes:
The entire game runs on a grid. During building this, instead of placing walls and pellets manually one by one, i generated the map from a simple grid of numbers (the array i was talking about earlier) where 1 is a wall, 0 is a normal dot, 2 are ghosts, and 3 is a power pellet.
The game works in such a way that it whenever the pacman moves, the game clears the screen, redraws the map, calculates any collisions against walls or ghots using maths (pythagoras), and updates everyone’s positions. Also, to keep the code clean, the ghosts are grouped into a array, which makes everyhing so much easier because instead of me having to manually change something for each and every ghost, i can just use the js forEach() function to just apply the changes to all of them easily.
I initially tried to control pac-man using normal movement where the pacman move pixel by pixel. BUt the problem was that when i pressed up to turn a corner, if pacman was even a bit off-center from the hallway, he would jump to the center of the hallway and then perfectly rotate and then continue moving. THis looked kinda annoying and badly made so i had to fix this.
To fix this, i built this function whic now calculates the exact center of the current grid square. And if i try to turn, the game checks if pacman is close enough it would allow the turn but if it isnt, the turn wouldnt register
When i first made the moving and turning parts, i made the game to remember my intended turn forever. Why? because when i played pacman to see what i owuld have to build, the pacman responded to my turn even though i was a bit behind the corner. SO i made it that if I pressed up halfway down a long corridor, the game would remember that input and forcefully turn pacman upwards the moment he reached the next intersection which was a bit later. But the thing was it felt like playing on autopilot and it felt weird.
So i gave the controls a this sort of buffer time where when a key is pressed (like up or down), it is only remembered for about a quarter of a second. If I press the key right before a turn where he isn’t aligned with the hallway yet, the pacman turns properly a quarter of a second later. If I press it too early, the command simply expires, and he continues driving straight.
Another challenge that i faced was when i madae the power pellet aspect of the game. The problem was when a power pellet was eaten, I forced all ghosts to turn blue as long as the power pellet was active. But if pacman ate a ghost, it would respawn in the center box and immediately turn blue again because the timer was still running. It looked safe to eat cus it was blue, but when i tried eating it, i died.
To fix this, i added a variable called isVulnerable that every ghost has. Now, the game only paints a ghost blue if isVariable is true. The moment a ghost is eaten, it flips to false, and it spawns normally in its normal color.
Before moving on to the third game in the Neocade (which is probably going to be Asteroids), I needed to take a step back. I decided to dedicate this entire session to improving the UI I already have and doing some debugging. Here is a summary of the changes I made:
I realized the arcade monitor was looking a bit too clean. I used CSS linear gradients to add a half transparent scanline effect across the entire screen. It instantly gave the game a genuine 1980s retro texture.
In Snake, the flat colored blocks for the body and apple looked kind of boring. So, i used html canvas shadowBlur and shadowColor to give the snake and apples like this glowing effect. I also swapped the apple to appear as a circle so it looks better and is easier to distinguish from the snake.
To make the game more fun and realistic, I implemented a high score system for Snake using localStorage. So, instead of wiping the browser’s memory every time the game ends, the high score is stored locally so the user can try to beat it later. I also added a “Press Space to Play Again” listener to make restarting much smoother.
I found a bug in Pong where, if the ball traveled right against the edge, it sometimes vibrated and never bounced off. My original logic essentially said, “If the ball goes past the wall, reverse its speed.” However, at high speeds (in harder modes), the ball would go so deep into the wall that reversing it once didn’t push it completely out. On the next frame, it was still in the wall, so it reversed again and again, creating this vibration.
To fix this, i changed the code to teleport the ball back onto the exact edge of the canvas. i then used Math.abs() to force the velocity in the correct direction (e.g., forcing a positive downward speed when hitting the ceiling) rather than blindly flipping the sign.
When the snake collided with a wall or itself, its head went past the wall before the Game Over triggered. The problem was i was updating the snake’s coordinates first, then checking for a crash. Because the head existed outside the canvas before the game froze, it disappeared on the Game Over screen.
To fix this, i rewrote the movement function to calculate the nextX and nextY coordinates, checking them against the boundaries before actually moving the array. Now, the game freezes with the head pressed against the wall.
There was a small bug in Pong where the computer’s paddle crossed the border of the screen when the ball was close to the floor or ceiling. Because the ai’s paddle follows the ball’s center, the top or bottom half of the paddle would move off-screen.
To fix this, i added a hard limit on the top and bottom of the canvas that completely stops the paddle from moving past the edges.
The Snake game field itself was too small, leaving a ton of empty space on the arcade monitor (visible in my previous devlog’s screenshot). So, I expanded the size of the Snake game field to take up a much larger portion of the pink box’s space.
My Pong difficulty logic was a mess. The ball speeds for different levels were handled in button clicks, and the computer ai speed was handled by a bunch of if/else blocks. Also, my “Easy” mode nerfed the player’s paddle speed so badly it made catching fast, steep angles physically impossible.
To fix this, i centralized all difficulty variables. I added an aiSpeed parameter directly to my startGame() function so every speed value is now controlled from one single place, which made everything so much easier. I also buffed the player paddle on Easy mode so the game always feels fun and doable, instead relying on the ai’s speed to adjust the difficulty.
Since the pong game was working really well, i moved on to implementing the Snake game. Here is a breakdown of how I built it:
Instead of trying to move a single object (like i did with pong), I made the snake an Array of coordinates. To make this array of coordinates move, I didn’t move every coordinate. Instead, I calculated where the new “Head” of the snake should be based on the the input given by the user (arrow up, down and so on). I used unshift() to add that new head to the front of the array, and used pop() to delete the last block of the tail. So essentially, instead of moving, its just that new blocks spawn at the from and ones at the very end get deleted.
If the new head coordinates match the apple’s coordinates, I simply skip the pop() function for that frame. This means the last block of the snake is not deleted which mean it effectively just grew by one block.
Overall this wasn’t too hard but i originally made a mistake of having the logic and the ui of the snake game in the smae index.html and main.js file as for hte pong game which led to like a couple of mistakes that took a while to fix cus i got confused. So, i just added a nwe snake.html and snake.js file and connected all of them together. I also spent a bit of time trying to style the snake game to look good but this is the best i could do for now (see attached pic)
This session took longer than expected and that’s mainly because i spent a good amount of time trying to find the right color combos and stuff. Here is the summary of the changes i made, how i made them, and the challenges i faced:
The first change was building the actual UI. In my prvious sessoin, i just had a plain pong game but that’s definitely not enought so i aimed to build a proper website. I wanted to keep it simple so i built all the menus and stuff in one page instead of different pages. See the attached picture to see what i did
This change is about improving the pong game. I made two main changes:
i connected the pong interface to the main interface, which wasn’t hard and didn;t take up a lot of time
the second change was adding difficulty levels into the game. I added an easy, medium and hard mode. THis is also took a bit longer than expected because i couldnt get the diffiuclties right. By that I mean that it was hard trying to find the right wat to make it difficult to play the pong game. I was stuck between two different options:
One was keeping the speed of the ball same but just making the omputer better. This essentially means bridging the gap between the ball speed and the computer speed.
the second way was increasing the ball speed as the difficulty increased.
I spent like a chunk of time trying those two out, and in the end, i chose the second way. A faster ball just felt better than a better oppoenet but the same speed ball.
The aim of this project is to create an arcade website with many arcade games available to play in your own browser. Here are the changes i made in this session
I set up my environment on vscode and set up a github repo. This didn’t take too long
I coded a full pong game into the website. THis is just the initial stages and i just wanted to start somewhere. The pong game is a singleplayer game (for now) where you play against a computer and there’s a scoreboard tracking your scores. It wasn’t too challenging except perhaps coding the computer engine to play against you but I managed to figure that out. Here is how i built the computer that plays against you:
I wrote a simple engine that tracks the ball’s Y-coordinate. If the ball is above the paddle, the paddle moves up; if it’s below, it moves down. But there was a problem, if the paddle could keep up with the ball, it would never lose so i made it such that the speed of the ball is slightly higher than that of the paddle, meaning it is still possible for it to lose.
Since pong is finished and is playable, my next goal is building the actual NeoCade ui and adding this game into the menu