Course:CPSC312-2021/Breakout
Breakout
Authors: Yean Shu, Jason Ueng, Daniel Hou
What is the problem?
We will recreate the classic arcade game, Breakout, using Haskell.
"In Breakout, a layer of bricks lines the top third of the screen and the goal is to destroy them all. A ball moves straight around the screen, bouncing off the top and two sides of the screen. When a brick is hit, the ball bounces back and the brick is destroyed. The player loses a turn when the ball touches the bottom of the screen; to prevent this from happening, the player has a horizontally movable paddle to bounce the ball upward, keeping it in play." (https://en.wikipedia.org/wiki/Breakout_(video_game))
What is the something extra?
The pong game we referenced was a one-screen game with a simple gameplay loop and nothing else. We tried as much as possible to make a more traditional arcade game. Our game starts out at the title screen, where the player can select from different game modes (Standard & Time Attack), as well as four difficulty levels. In addition, the game also has end conditions, either when the ball becomes too low to hit, or when all the bricks have been destroyed; with each displaying a separate end screen. Lastly, we also implemented a high-score system, where you can try to beat your fastest time.
What did we learn from doing this?
The most important thing we learned was an understanding of what types of programs functional programming should be used for. Although we have seen many examples of how Haskell can be used for programming games, those games were turn-based games, such as the counting game. However, breakout is a real-time game with an enormous set of possible states (one for each possible frame, score, location of the ball, paddle, bricks, etc.). As such, functional programming is very effective when we have to change between different distinct states, e.g., from the title screen to the gameplay, but much less effective when it comes to the player-controlled portion. Therefore, choosing to remake breakout was not necessarily to best idea for the project
In more practical concerns, this project taught us much more about how IO works. Since gloss forces the use of IO in its built in functions, this necessitated that we learn how to use IO. The biggest problem that we faced in regards to this question was how to load external images. Since the image itself should not be considered to be part of the game state, we needed to find a new way to bundle. In the end, we ended creating a new data type called an Archive, which was essentially a tuple, with the first element being the actual game state, and the second element being an IO image. This way, we could allow the image to be within the scope of the rendering functions.
For future projects involving functional programming, we would consider something with a set of states that is much more handleable.