At the beginning…
When I started this project, I was already quite familiar how I want to implement this game. I wanted to created a version where both paddles would be controlled by players, so I would not need to create any AI to control either paddle. Event though the complexity of building a simple AI would not be a huge task, it would still additional code complexity in the implementation. I also wanted to keep ball directional rotations simple by only allowing four static directions for the ball. This seems to be quite typical way to implement a simplified version of the ball movement in different kinds of Pong implementations.
The mentioned features would be in contrast with my previous Pong implementation that I made for my Master’s Thesis evaluation. That implementation was far from simple, as it contained AI, complex ball directions changes on paddle hits and it also contained online features with four different kinds of consistency-responsiveness maintenance techniques. Perhaps it was time to create a simple version of the game this time.
When I started, I knew that I want to divide the game into three separate scenes. One scene for the welcoming message and game instructions, another scene for the game court where the match would be played and the third scene for the overall results. It was quite easy to figure out that each of scene has only a couple entities and they would be quite easily separated from each other. It was also quite easy to deduce that my game states could be easily used as game states as well. See the following illustration about how the main game state/scene structure was built.
I decided to use enter, exit, update and draw functions for each scene. The enter function of the upcoming scene and the exit function of the previous scene would be automatically called with the function that acts as the state changer. I think that this state machine kind of structure worked quite well, as state transitions were quite smooth. Draw and update functions are being called only to currently bound scene, which makes it easy and efficient to change the active scene on-the-fly.
Game entities and especially their logical update function took me the most of the time. It was quite easy to start with the welcome scene, as it only contained a couple text entities that were required to instruct the players how the play the game. I was quite satisfied how easy it is to draw and handle text on the canvas by using the canvas 2D API. Couple lines of code and the welcome scene was finished. Not a bad journey on that one at all.
Court scene was the biggest scene, which is not a surprise as it would contain the major of the game logical structures. I decided to split scene entities as the court background, score indicators, paddles, goals, walls and the ball. Drawing the entities was quite trivial to implement as all visible entities were formed from rectangles and luckily the canvas 2D API provides an easy way to draw these by using the fillRect(x, y, width, height) call. I also implemented score indicators to be rendered with the fillRect as I wanted them to be visualized in a old fashioned way i.e. with numbers formed with rectangles.
I added and used a simple AABB structure to detect collisions in the court scene. This may be a bit overkill as the collisions could be detected also via some number limits. But well, it was a nice addition to this journey as I was already familiar with the concept of AABBs. I also actually considered that perhaps I could write a blog post about AABBs and their different kinds of implementations. It would be nice to deep dive into the AABB implementation details as well and write something about them.
Lastly, but not the most meaninglessly I added the end game scene. It was also quite trivial to implement as it only contained a couple of text entities and a simple button listener to wait for the user to press the enter key.
Thanks for reading!
Gameplay video in YouTube: https://www.youtube.com/watch?v=McVMjHzR6uw
Game source code in GitHub: https://github.com/toivjon/html5-pong