NeoCade
- 4 Devlogs
- 11 Total hours
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