The D3 Library!
Last Saturday, my pair and I built an awesome game in D3. It was one of the most exhilarating experiences I've had at Hack Reactor. A little reminiscent of doing Mega Startup Weekend in the mobile gaming track almost a year ago.
Tuhin and I started our two day sprint with 4 repos for the assignment. This means literally working on 4 small projects in the span of two days. Marcus wasn't kidding when he said we probably wouldn't get to the end because even at a glance it looked like each project would take 4-8 hours. The first was on html/css layout which we decided to move on from after the part (replicating Google pixel by pixel).
We decided to move to the next part mainly because we were so excited about the library. D3 is actually one of the reasons I got excited about Javascript in the first place. D3 is a visualization library that allows you to bring your Javascript into a 2D/3D animated space. Here are some great examples: https://github.com/mbostock/d3/wiki/Gallery. Notice how a lot of these visualizations are less than 50-100 lines. D3 brings together SVG (vector-based graphics), CSS, html and selectors/animations that feel like jQuery.
The initial assignment was to recreate this game. http://latentflip.com/LearningD3/collider/. It looked daunting at the beginning but after looking at the code it became easier to break it into smaller chunks. The main thing I realized after playing the assigned game is that the game sucked! There was really no underlying game design besides avoid dots. Also no sense of progression. Tuhin and I immediately saw an opportunity for improvement. Given these features as a rough shell of a game, how could we make this fun? Before we dove too far into the code, we began debating possible features. Some of the ones that came to mind were:
Capture flags that randomly popped up around the screen.
King of the hill - you only get points while you stand in certain zones that appear randomly.
Eating some of the dots.
Growing as you eat more dots.
After we brainstormed a bit, we also came to the conclusion that given time constraints and good game design, we should probably limit the feature set to the top 2. I really wanted to the game to start out easy. Any user should be able to grasp the concept in the first 10 seconds or after they lose without instruction. I also wanted to the game to progress in difficultly as the game went on. Also, unlike the assigned game, I didn't want it to feel like a constant cluster duck. All these things considered, we finally came to the idea of eating pink dots and avoiding blue ones. Simple game design right? The user would start out with one pink dot on the screen and no enemies. After eating one, one pink dot and one blue dot would appear. All the dots move around constantly so as you eat more pink dots and more blue dots appear, it gets harder and harder. By the time you've eaten 20 pink dots, there are 20 blue dots flying around the screen for you to avoid!
Translating this to code was difficult but not the hardest assignment we'd had. I think part of that is thanks to my pair. He had a very good eye for when something wasn't making sense and that we should just read the documentation. The more I code the more I realize how often times debugging through the process of trial/error or deductively isn't always the best way. I'm finding it more and more valuable to get exact definitions from documentation and using the debugger to inductively finding the cause of issues.
The hard parts about grasping the D3 library at first were the primary functions it uses to stage data and to render it. It D3 workflow basically goes like this:
Create a d3 object and append it to a point on the DOM. Set key attributes like height/width etc. Declare any special methods that need to be applied to the entire D3 object.
Decide how you're data flow is going to work. D3 works on the paradigm of data entering, updating and exiting.
.data(data) - the data function is applied to the svg.selectAll(DOM elements you want to interact with). When it's called it compares itself to the number of nodes that are currently rendered on the DOM and from that comparison it decides how many nodes need to be entered or exited. .data() does not deal with the data itself, rather just the number of elements/nodes. This is one of the hardest parts to understand at the start. It doesn't care what data you feed it, just the amount.
.enter() - is a method applied after .data() and it informs what you want to do with the extra nodes that are being create. for instance, if there were 20 live nodes on the DOM when .data() is called on with 25 elements, .enter() now knows that it needs to create 5 new nodes. The code you write after .enter() tells the app what to do with those 5 new nodes.
.exit() - is also applied after .data() and like enter is what you do with the nodes that were in excess. often it is just a .remove() command which removes them from the DOM.
That is the gist of D3. In our game we had a setInterval to update the dots entering/exiting and to move them a around. And a second setInterval to run constant collision detection on the dots.
After dedicated probably 10 solid hours to our game, it was ready by 6pm on Saturday. We were super excited to finally get it into people hands and happily people got hooked. One of the students was locked in for 30 minutes trying to break the record (which is now 33). Try it out for yourself! Happy gaming!
http://bit.ly/13hmNep












