I have been wanting to write some more Clojure code for awhile. Since I got a (somewhat) playable version of the Haskell Draughts implementation working, that gave me the time to do something short in Clojure. Although I have written some Clojure before for Project Euler, a lot of it was non-idiomatic, and I have not only read parts of a few Clojure books since then, but also experienced the beauty that is Haskell.
I decided to implement a quick game–Breakout. Although there is already an implementation of Breakout using Clojurescript, I did not think to check before I started. This code is largely my own, with inspiration from Clojure Tetris for the game loop, user-input, and ideas about how to manage state.
In addition to practicing with Clojure, I spent the time to get Aquamacs up and running with clojure-swank so that I’d have an integrated REPL to use while editing, and learn some of the basics of using Leiningen for project management. I’m normally a vim user, so using emacs was a big thing for me, and I’m definitely not nearly as productive with it.
My implementation draws using Java’s AWT Canvas to render the game board. I haven’t worked with it since around 2004 or so, when I implemented a card game for a class on GUIs and had to render some custom controls for card hands. So, I started out very basically. In my first commit (9040c), I create a Swing JFrame, and update its title with the game loop iteration. My next commit (d1ac2), adds a place holder method that will render the game state each run loop. At this point, it just paints a red rectangle in the frame.
In the next two commits (ffa93 and d409e), a paddle data structure is added to store the location and size of the paddle. A function to render the paddle is added, and input handlers (mostly taken from the Clojure-Tetris project) to move the paddle.
This is the theme of the subsequent commits. I add a ball data structure, then a function to render the ball, then ball movement. I think its utterly important to work in very small bite-size chunks of functionality. Whenever I fail to do this, a small, toy project, becomes a lumbering sloth of a project that just drags on and on. For these projects, I often have to find a spare hour here and there, and its sometimes really hard to come back to a project when I haven’t taken this bite-size approach.
If you’re interested in checking out the project, the full source is available on Github. There are issues with the implementation, of course. Collision detection could be much better (the ball can actually fly through the side of blocks). Still, I’m happy with the current state of the project, and my original goal is satisfied. Below’s a short screencast of the game.