Exploring JavaScript Games on IE6
My first experiment with JavaScript OOP, and remade the NES game Battle City.
In early 2007, I had only half a year of high school left. Over the previous two years, my grades had collapsed. I didn’t care. I had never wanted to be in school in the first place. But my family insisted that I go to college, so I dragged myself through what felt like the most miserable months of my life.
After graduation, I bought my first phone. Whenever I got a new gadget, I liked finding something fun to do with it, so I also bought a book on J2ME programming. The book itself was unremarkable, and I wasn’t especially interested in mobile development, but the built-in game APIs in J2ME caught my attention. I started wondering whether I could build something similar in JavaScript, while also refactoring the messy code from my earlier browser games into something cleaner.
This was the age of IE6. No sane person would try to build a complex game in JavaScript when Flash existed. ActionScript had classes and static typing, so many mistakes could be caught at compile time; JavaScript, by contrast, often waited until runtime to reveal a typo. Worse still, HTML didn’t even have canvas yet.
But I was not a sane person. Ever since I first learned web development, I had treated Flash as a kind of heresy. Doing the same thing in pure HTML felt like the ultimate glory, despite the immense suffering it entailed.
The first challenge was how to implement OOP in JavaScript in some elegant way. I looked up countless approaches, but none of them felt graceful. They all came down to manually manipulating prototypes to simulate methods and inheritance. I didn’t have a better idea, so I accepted that awkward foundation and started building the game library anyway.
The first class I wrote was Layer, a base class for everything visible on the screen. Internally, it created a DIV and exposed methods like SetX and GetX to manipulate coordinates, dimensions, background color, visibility, and other basic properties.
Next came Sprite, a subclass for displaying one frame out of a larger image. I had already used that trick years earlier, as described in the “Yet Another Trick” post.
After that I added classes for tiles, text, and other objects, making sure that the game logic itself no longer had to deal with raw DOM details.
Once the display layer was wrapped up, I turned to input handling. In my earlier games, I had processed logic directly inside event callbacks, but callback timing was unpredictable. This time I wrapped keyboard and mouse input in a controller that simply recorded the latest state, which the main game loop could poll whenever it needed. Polling made timing much easier to manage.
I even wrapped counters into their own abstraction. A counter is a trivial thing — just a current value, a maximum value, and some increment, check, and reset operations — but I still wanted a cleaner way to use them. So I hid those details behind a small class interface. It made the game logic much easier to read, because counters appear everywhere in games.
It took me about a month to finish the library. After that, I decided to use it to fully recreate an NES game. I chose Battle City because its scenes were relatively simple. More importantly, I had loved it as a child and knew every detail by heart.
Since each tank in the game can face four directions, I briefly considered adding rotation support to Sprite. In Internet Explorer, rotation and even matrix transforms could be done with DXImageTransform filters — I had previously used them to make a cube effect. (an idea that struck me while drawing cubes in math class — I stayed up several nights to make it work)
But IE filters were not portable to other browsers, which were starting to emerge by then — I often used Opera myself.
Get EtherDream’s stories in your inbox
Join Medium for free to get updates from this writer.
So instead of rotating images at runtime, I just pre-rendered separate sprites for each direction.
The second challenge was the bricks. Anyone who has played Battle City knows that bricks can be blasted into many small fragments. Without canvas, every fragment would need its own DIV, which could easily explode into a huge number of DOM elements. To keep performance acceptable, I used the same trick as before: I pre-rendered images for many possible fragment combinations, trading space for time. That reduced the number of elements greatly.
Once those two problems were solved, the rest was straightforward. I took countless screenshots of the original game and zoomed them in as far as possible, trying to match everything pixel for pixel. It took me nearly another month to finish the remake before summer vacation ended.
In the end, it was around four thousand lines of code, written entirely in JS and CSS, and it even ran in IE5.
https://www.etherdream.com/funnyscript/battlecity/
Movement: WASD, Fire: KL, Rapid Fire: IO, Confirm: Enter
Like the original, the first screen lets you choose a stage.
After I started college, I kept thinking about JavaScript OOP. One day I had a strange idea: although I despised Flash, I could still make use of its IDE, write the code in ActionScript, and then convert it into JavaScript afterward. The syntax of the two languages was similar enough that it seemed possible.
So I reimplemented the game library against the Flash API and ported the game logic to ActionScript. In the process, I even discovered bugs and design issues I hadn’t noticed before. I had to admit that Flash really was more powerful — though, in my mind, that did not conflict with my belief.
After that, I wrote a small converter that stripped type annotations from ActionScript and transformed its class-based OOP into JavaScript prototype operations. It was only an experiment, so instead of building a proper lexer or parser, I simply used regular expressions.
Just as I was getting ready to push that tool further, I discovered a language called HaXe. It could compile to multiple targets, including both JavaScript and Flash, while supporting classes and static typing. It was almost exactly the language I had been imagining.
So I ported the game again, this time to HaXe. That let me debug it inside the Flash IDE while still generating JavaScript output. The online demo was built that way.
Later, I learned about TypeScript. It was more powerful still, and eventually I migrated all of my JavaScript projects to it. But I never ported this game again. By then, it had already served its purpose.
I once briefly shared it on my blog, where the original source code is still available. It’s pretty rough though — back then there was no module system, so every module was loaded as a separate JS file. The HaXe version was more elegant, but that source code got lost on my college computer.







