Degralder.com

The Making of the Breakers Game

I wanted to write a simple game for my website that I could finish in a couple of days. Here is the story of how I ended up making the Breakers game.

Choice of Game

The first question I had to answer was what kind of game I wanted to make. I had been working on a pinball game at the time, but figuring out the math and getting reasonable performance for pinball was taking a lot more than a couple days effort. I needed something straightforward that would be easy to make run fast.

The first things that came to mind were games I had already done: Snake, Game of Life, and Space Invaders. Space Invaders is the most interesting game in that list, and I knew I could do it without getting caught up on performance issues because I had already made a couple of Space Invaders clones that went plenty fast. I decided to use Space Invaders as my inspiration.

There was a time I enjoyed playing the XGalaga clone of Galaga. I remember playing similar games when I was younger, where you shoot aliens, dodge their bullets, and power up your ship’s abilities. It’s a good game concept with plenty of room to grow and simple to start off.

Rather than do another Space Invaders clone, I wanted to do something new. Unlike my previous Space Invaders clones, I was going to put this game on the internet. I don’t know if someone would come after me for posting a clone of Space Invaders on the internet; it’s more interesting to create something original regardless.

Graphics Design

Creating pretty graphics for games is hard. To give you a sense of my artistic ability, here are samples of some of my finest pixel art:

box1 box1
box2 box2
box3 box3
box4 box4
box6 box6
box7 box7
pyramid1 pyramid1
pyramid2 pyramid2
lake lake

I would rather not spend a lot of time trying to create graphics that don’t look that great. Instead I could just draw everything using rectangles. Rectangles are easy to implement and cheap to draw. The gameplay is not negatively impacted in this case, and I could pretend I did it on purpose for stylistic reasons.

Here is the graphics design I came up with for the game:

Object Graphical Representation
Background Black Rectangle
Ship Green Rectangle
Bullet White Rectangle
Enemy Red Rectangle
Bomb Orange Rectangle

Programming Language

The game is for my website. I want people to be able to play it without downloading or installing anything, and it should work on most major browsers. I want the game to be served as a static web page, where all the game logic runs in the client.

JavaScript seems natural to use as the programming language. I thought about trying WebAssembly, but JavaScript feels like a simpler place to start. I could switch to WebAssembly later if there are performance issues with JavaScript.

Graphics API

I thought about either Scalable Vector Graphics (SVG) or WebGL for drawing the (rectangle) graphics. My memory from using SVG before is that there isn’t a good standard interface for modifying SVG on the fly with JavaScript in a high performance way. You have to either write SVG as text on the fly or use browser specific APIs. WebGL feels like a better fit for a game that redraws for every frame and can scale up to much more interesting graphics more easily in future iterations of the game.

Enemy Behavior

The most interesting question about the game is how the enemies should behave. Should it be like space invaders, a formation of enemies that slowly advance? Or like Galaga, where the enemies fly in various patterns around the screen? I was thinking you would start with a few enemies and add more over time so the game steadily increases in difficulty as you play.

As you add more enemies, how do you keep them from running into each other or overlapping? I don’t want to have to do O(N^2) collision detection or other fancy logic to make collision detection fast.

Some ideas I considered:

These evolved into the idea of a fixed grid where enemies randomly move left, right, or down towards the player. We only allow the enemy to move if the location they want to move to is empty. We can easily track which positions are available using a 2D array of booleans, and we can use some simple math to tell which row and column of the grid a bullet is traveling over.

Having a grid of rectangular enemies made me think of the game Breakout, which has a grid of rectangular blocks. The blocks could be enemies you shoot. I took this as the inspiration for the game’s title: Breakers.

Implementation

Now that I had a solid idea of what the game should look like, how it would play, and what programming APIs I would use to write it, it was time to get started with the implementation. I implemented the game in steps, with each step focusing on a different aspect of the implementation I would have to figure out.

Hello Triangle

The first step was to figure out how to draw something on the screen using WebGL.

I had done some basic work with OpenGL before, but never anything with WebGL. The sample code I had for working with OpenGL was based on glxdemo. A search for WebGL in the browser brought me to WebGL tutorial - Web APIs | MDN - Mozilla. I attempted to use the skeleton from the WebGL tutorial with the sample code from glxdemo to draw a triangle to the screen.

The trouble is, my glxdemo code used things like glMatrixMode, glOrtho, and glRecti, none of which I could find in WebGL. I suppose that’s the old way of doing things, and everything in WebGL is based on the new way of doing things, namely writing shader programs.

I dug into the WebGL Specification and man pages for OpenGL from the opengl-4-man-doc debian package to understand how to draw a triangle using vertex and fragment shaders. I find the APIs and programming paradigm to be pretty obscure, but I understand why they are that way.

Drawing the Ship

Once I had figured out how to draw something to the screen, the next step was to draw the ship to the screen. This meant figuring out how to draw a rectangle instead of a triangle, and how to position it different places on screen.

It’s not much of a stretch to go from a triangle to a rectangle, so this phase was pretty easy. I took the opportunity to clean up the code as I went.

Moving the Ship

To get the ship to move left and right based on keyboard input meant figuring out how to process keyboard inputs and how to animate the graphics. W3Schools helped with keyboard inputs and the WebGL tutorial had a section on how to use requestAnimationFrame for animations.

At this point I had a green rectangle ship that I could move left and right on the screen using the keyboard.

Dropping Bombs

Next I added bullets and enemies. It took some futzing to get random movement of the enemies to feel reasonable.

Initially I envisioned having the enemies drop bombs on the player’s ship. Part of the fun of the game would be to dodge the bombs while shooting the enemies. At this point in the implementation I could shoot enemies with bullets from the ship, and the game was fun enough to play. I decided it was good enough; no need to go to effort to add bombs.

Game Over

That last thing to do was deal with the end game condition. I decided not to worry about having multiple lives. The game would end when the first alien reached the bottom. But how would I indicate that to the player?

Text with WebGL sounds like work to me. I thought about rearranging the enemies to spell out the word ‘END’ or something, but there wasn’t enough space. I decided to just change the gray borders to red at the end of the game and stop the game animation at that point.

And thus the Breakers game was born.

Retrospective

There’s something cool that happens when playing the game, when an enemy jumps forward a couple of rows, almost at the bottom of the screen, and you go to shoot it but can’t line up the ship at the right place. This feeling of frantic panic and overwhelming relief when you manage to hit the thing instead of losing the game. That’s not something I anticipated when I set out to write the Breakers game. That’s what makes this feel like a success.

The Breakers game is by no means perfect. Here are some of the things that stand out to me as opportunities for things to improve next: