Showing posts with label javascript. Show all posts
Showing posts with label javascript. Show all posts

Monday, May 9, 2016

Add Gamepad Support to a Phaser Game

It seems like I haven't written a blog post in forever! It's actually been less than 2 weeks. Right before I took a break, I wrote a little about my new NES-style Bluetooth gamepad. I've been trying off-and-on ever since then to get my 8-bit style platformer to work with it, and today I finally had some success!

First of all, it needs to be said that support for gamepads in the browser is very inconsistent. The W3C's Gamepad API document is still a working draft after all these years (I first read about it and tried it out in 2013). It seems as though Mozilla and Google have some different opinions on how it should work, because the way you interact with the devices varies significantly between Firefox and Chrome. Phaser provides gamepad support through the Gamepad object, but the documentation carries a warning about the volatility of the specification.

Here's what I learned when I tried to use it...

I started with some of the examples on Phaser's site. They worked, most of the time. Let me explain. In theory, working with a gamepad in Phaser is simple. You get a gamepad object, setup a callback to handle the detection of a gamepad device, and bind to buttons in that callback. Then you start the gamepad polling.

function create() {

    // ... setup stuff ...

    var jumpButton = null;

    controller = game.input.gamepad.pad1;

    controller.addCallbacks(this, {
        onConnect: function() {
            // you could use a different button here if you want...
            jumpButton = controller.getButton(Phaser.Gamepad.BUTTON_1);
        }
    });

    game.input.gamepad.start();

    // ... other stuff ...

}

function update() {

    // ... other stuff ...

    if (jumpButton.isDown) {
        // jump code goes here!
    }

    // ... other stuff ...

}

Much like you do for keyboard input, you can set up the buttons you want to listen for in create and then perform actions based on their state in update. And this works pretty well - in Firefox. Chrome, on the other hand, has some issues. Phaser's example code, much like my example above, works most of the time in Chrome when the code gets executed very quickly after the page loads. But if you put enough setup code in front of your gamepad initialization you'll be wondering, like I was, why your gamepad never connects.

I had to dig into the Phaser code in order to figure this out. It works consistently in Firefox because Firefox waits until the first time a button is pressed on a gamepad before it emits a gamepadconnected event from the window object. Phaser catches that and sets everything up, calling the onConnect function when complete. In Chrome, however, gamepads just show up magically at some point after the page is loaded, in an array-like object accessed by calling navigator.getGamepads(). Phaser checks this list constantly, and when things appear for the first time, it makes all the internal setup calls. And right there's the problem! If the gamepads appear BEFORE my onConnect callback function is set up, I missed the boat. A default, no-op callback got executed instead and my gamepad buttons never get set up!

There was no work-around for this that I felt was acceptable, so I actually forked Phaser and fixed the problem in the Gamepad object's code. It was a fairly simple fix - I just don't start polling for those gamepad objects until after the call has been made to game.input.gamepad.start().

I forked off of version 2.4.7 and submitted a pull request, so hopefully my fix makes it in to the next Phaser release and the rest of you won't have to deal with this problem like I had to! If you can't wait, try using my fork and gamepad branch.
UPDATE: My pull request was merged, but not in time for 2.4.8. Look for this fix in the 2.4.9 release!
If you're just interesting in playing the game I've been working on, you can do that here: http://amphibian.com/eight-bit. The full source code is available on GitHub. If you're just interested in viewing today's comic, you can do that here:

Amphibian.com comic for 9 May 2016

Monday, February 1, 2016

Generating Color Gradients with JavaScript

The comic frames with the color
gradient backgrounds.
For the comic on Friday, I had to generate a color gradient between the full-brightness daylight color in the third frame and the nighttime darkness color in the fourth frame. Since the point of the comic was to adjust the brightness using a slider with 20 positions, I needed 40 colors (including the 2 starting colors) so that when the brightness was all the way down both frames would have the same background. They would meet in the middle.

It was actually a very nice comic. On the right you can see the frames with the color gradients, but the real comic is interactive - go play around with it if you haven't yet!

To generate the gradient of colors, I found a set of JavaScript functions which I will share here. I can't take credit for it, all I did was rearrange some of the code and re-order the output (the original seemed backwards to me) but it is very nice. I am keeping it in the source code for the Amphibian.com comic editor in case I ever need it again.

Here is the function. Calling it should be self-explanatory. Note that the colorCount parameter will be the total size of the output array INCLUDING the start and end colors.

function generateColorGradient(colorStart, colorEnd, colorCount) {

    /* Convert a hex string to an RGB triplet */
    var convertToRGB = function(hex) {

        /* Remove '#' in color hex string */
        var trim = function(s) {
            return (s.charAt(0) == '#') ? s.substring(1, 7) : s;
        };

        var color = [];
        color[0] = parseInt((trim(hex)).substring(0, 2), 16);
        color[1] = parseInt((trim(hex)).substring(2, 4), 16);
        color[2] = parseInt((trim(hex)).substring(4, 6), 16);
        return color;

    };

    /* Convert an RGB triplet to a hex string */
    var convertToHex = function(rgb) {

        var hex = function(c) {
            var s = "0123456789abcdef";
            var i = parseInt(c);
            if (i == 0 || isNaN(c))
                return "00";
            i = Math.round(Math.min(Math.max(0, i), 255));
            return s.charAt((i - i % 16) / 16) + s.charAt(i % 16);
        };

        return hex(rgb[0]) + hex(rgb[1]) + hex(rgb[2]);

    };

    var start = convertToRGB(colorStart);
    var end = convertToRGB(colorEnd);

    // The number of colors to compute
    var len = colorCount - 1;

    //Alpha blending amount
    var alpha = 0.0;

    var ret = [];
    ret.push(convertToHex(start));

    for (i = 0; i < len; i++) {
        var c = [];
        alpha += (1.0 / len);
        c[0] = end[0] * alpha + (1 - alpha) * start[0];
        c[1] = end[1] * alpha + (1 - alpha) * start[1];
        c[2] = end[2] * alpha + (1 - alpha) * start[2];
        ret.push(convertToHex(c));
    }

    ret[len] = convertToHex(end); // last color might be slightly off

    return ret;

}

One thing that I noticed is that for colorCount values greater than 13 the final color was not quite the requested final color. Rounding error I suppose. That's why I explicitly set the last element in the return array to the end color, if you were wondering.

Using jQuery, I wrote a simple demonstration of the gradient function:

    var things = generateColorGradient("#CC0033", "#FFFF66", 15);
    for (var i = 0; i < things.length; i++) {
        $("body").append("<div style='background-color: #" + things[i] + ";'>test</div>");
    }


...which produces the following output on a web page. Beautiful, isn't it?


Today's comic, on the other hand, contains absolutely nothing of any technical interest. You should still read it though. And if you haven't read all the other Amphibian.com comics, what are you waiting for? They don't take that long to read. Start today!

Amphibian.com comic for 1 February 2016

Monday, November 9, 2015

Single-Direction Collision for your Phaser Tiles

I was working on my platformer (full source code on GitHub) using Phaser, and I wanted to add some platforms to the map. You know, like you do in platformers. Specifically, I wanted to have some box-like things in the environment that the frog could jump on top of, but also walk in front of. Like those box things with the screws in the corners from Super Mario Bros. 3. Mario walked in front of them, but if he jumped up he would land on top and walk across them. You remember:

I wanted boxes like the one upon which Mario stands.

The tileset I was using had some things like that in it, so I used them and made some nice platforms in my sandbox level. It was then I realized that I had a problem. If I set the tiles that made up the boxes to collide with the frog, he could jump on them but not walk in front of them. Maybe if I just set the top tiles as having collisions, or put the lower halves in the background layer, I could walk in front of them. Yes, but I still couldn't jump straight up and land on top because the frog would bump into the top tiles from below.

I want to jump on these.

Phaser supports one-way collisions for physics bodies with the Arcade Physics module that I am using, but since I was dealing with a tilemap there didn't seem to be a way to set it up. When you want to set up collision with some of your tiles, you use one of the setCollision functions (setCollision, setCollisionBetween, setCollisionByExclusion). They don't take any parameters to fine-tune the collisions. Internally, those functions call setCollisionByIndex. Looking at the source for that function, I could see that every tile was indeed set to collide on all sides. It took me a little while, but I found a way to override that behavior and get the effect I wanted.

Here is the function I came up with:

function setTileCollision(mapLayer, idxOrArray, dirs) {

    var mFunc; // tile index matching function
    if (idxOrArray.length) {
        // if idxOrArray is an array, use a function with a loop
        mFunc = function(inp) {
            for (var i = 0; i < idxOrArray.length; i++) {
                if (idxOrArray[i] === inp) {
                    return true;
                }
            }
            return false;
        };
    } else {
        // if idxOrArray is a single number, use a simple function
        mFunc = function(inp) {
            return inp === idxOrArray;
        };
    }

    // get the 2-dimensional tiles array for this layer
    var d = mapLayer.map.layers[mapLayer.index].data;
    
    for (var i = 0; i < d.length; i++) {
        for (var j = 0; j < d[i].length; j++) {
            var t = d[i][j];
            if (mFunc(t.index)) {
                
                t.collideUp = dirs.top;
                t.collideDown = dirs.bottom;
                t.collideLeft = dirs.left;
                t.collideRight = dirs.right;
                
                t.faceTop = dirs.top;
                t.faceBottom = dirs.bottom;
                t.faceLeft = dirs.left;
                t.faceRight = dirs.right;
                
            }
        }
    }

}

Despite the weird-looking top half of the function that is just setting up a way of matching against either a single tile id value or an array of values, overall the function is very simple. It gets the 2-dimensional array of all the tiles in the given layer and loops over them. If the tile index matches one of the specified index values, the collision settings for that tile are altered in accordance with the dirs object. The dirs object should have 4 boolean fields, top, bottom, left, and right. A value of true for any of them indicates that you want Phaser to check for collisions with other objects coming from that direction. In my case, only top was set to true. I only want to cause a collision when the frog hits the tile from above.

Here is how I use it from my create function:

function create() {

    game.physics.startSystem(Phaser.Physics.ARCADE);
    game.physics.arcade.gravity.y = 1500;

    var map = game.add.tilemap("stage1");
    map.addTilesetImage("ground", "tiles");

    layer = map.createLayer("layer1");
    layer.resizeWorld();

    map.setLayer(layer);
    
    // set collisions on ground tiles
    map.setCollisionBetween(1, 275);

    // set collisions on tiles that are the top parts of the boxes
    map.setCollisionBetween(3354, 3356);
    map.setCollisionBetween(2900, 2903);
    map.setCollisionBetween(3714, 3716);

    // set those box top tiles to only collide from above
    setTileCollision(layer, [3354, 3355, 3356, 2900, 2901, 2902, 2903, 3714, 3715, 3716], {
        top: true,
        bottom: false,
        left: false,
        right: false
    });

    // ... other stuff ...    

}

The end result is just what I wanted - the frog can walk in front of the boxes and jump up to land on top of them. The following video shows the box-jumping in action.


And speaking of jumping on boxes - if it's that time of year at your workplace in which you check boxes on reviews of your coworkers, you might enjoy today's comic. In it, we find that the frogs have a more basic approach to the classic forced ranking system.

Amphibian.com comic for 9 November 2015

Wednesday, October 21, 2015

Bleeding Edge JavaScript Math

In today's comic, Science Frog finds himself on the bleeding edge by accident - literally. Just so I have a nice tie-in with that, I'm going to share some bleeding edge JavaScript math functions. Not literally. You won't actually bleed. Unless you cut yourself on your keyboard, in which case you really should get a better keyboard.

Why do I say this is bleeding edge? I guess I could say cutting edge or leading edge. I could also just drop the idioms and say that these are new language features. The first is only available in the Firefox nightly builds at the moment. How's that for the edge of some kind?!

What is that new feature? An exponentiation operator! That's right, no more need for Math.pow()! Just use double asterisks. This is a feature currently planned for ECMAScript 7 next year, but you can try it in a Firefox nightly build today (it may be included in next month's standard release):

var e = 2 ** 8;
var p = Math.pow(2, 8);

console.log(e === p);  // prints true

Not exciting enough for you? Come on, Java doesn't even have an exponentiation operator and it's been a legitimate language for at least 10 years! I guess Python does, but now all you Python devs don't have an excuse for not switching to JavaScript.

Now for something slightly less edgy. Since Math.pow() will become obsolete, I guess it's only fair that it get a new function. Added as part of ECMAScript 6 this year, Math.fround() is that function. Given a number, it returns the nearest single-precision floating point number. What? Try this (it works in standard Firefox releases since 26 and Chrome since 38):

var x = Math.fround(2.567);
console.log(x); // prints 2.566999912261963

var y = Math.fround(3);
console.log(y); // prints 3

var z = Math.fround(3.3);
console.log(z); // prints 3.299999952316284

I'm sure it makes sense now - Math.fround() gives you the most precise floating point equivalent of a number.

That's all I have to share today. I'm actually away from home this week - in the Dallas area for some software architecture training. But I did all the comics for this week before I left, so no problems there! Missing the comics is fround upon. Sorry, couldn't resist that one.

Amphibian.com comic for 21 October 2015

Monday, October 19, 2015

JavaScript Collections - Set

In addition to Map, JavaScript also got another popular collection type this year - the Set. As part of ECMAScript 2015, which is now mostly supported by Node.js, this new build-in object type was added to the language. It's also available on the client-side in Firefox, but it's probably best to keep it on the server side for right now.

So how does it work? Pretty much like you'd expect a Set to work. You can add values to it, but it can only hold unique values (contrast this with Array, which can hold multiple of the same object).

var s = new Set();

s.add("string value");
s.add(4);
s.add(false);

console.log(s.size); // prints 3

console.log(s.has(4));               // prints true
console.log(s.has("not in there"));  // prints false
console.log(s.has(3+1));             // prints true
console.log(s.has(false));           // prints true

s.add(4);            // no effect
console.log(s.size); // still prints 3

s.delete(4);
console.log(s.size); // prints 2

As you can see from the example, it supports the standard functions for adding, removing, and checking. Note that, just like Map, the type of objects that can be put in a Set are wide open. You can keep Strings, Numbers, Booleans, and even Functions in the same set. The Booleans are interesting - look at line 5 above. You can add false to the Set. Then s.has(false) returns true. But the fun doesn't end there. You can even put Infinity (NaN) in the Set if you want. Why would you want to? I have no idea, but it works.

var b = new Set();

b.add(4/0);
b.add(3/0);

console.log(b.size); // 1, Infinity added twice

console.log(b.has(1/0)); // prints true

Okay, enough of that. What else should you know about Sets? You can iterate over them just like Arrays.

var c = new Set();

c.add("one");
c.add("too");
c.add("tree");

c.delete("too");
c.add("two");

for (i of c) {
    console.log(i); // one, tree, two
}

The iteration will produce the contents in insertion order, which is why the above example prints one, tree, and then two. There's not really a way to re-order the Set.

Just like I said about Maps, I haven't really been missing them from JavaScript. There's plenty of ways to get around their absence. But now that they're part of the language, I'm sure I'll end up using one somewhere. Personally, I think Sets add more to JavaScript than Maps do simply because of the unique item enforcement.

Don't miss today's Amphibian.com comic. Laughter keeps you healthy.

Amphibian.com comic for 19 October 2015

Friday, October 16, 2015

JavaScript Collections - Map

I still can't fold them back up!
Ready to be confused? Okay, so you know that JavaScript has a map function on Array objects. It creates a new Array by applying a given function to each element of the Array. But now it also has a Map collection object. Now when you talk about a Map in JavaScript, are you talking about a function on an Array or a key/value pair data structure?

Those of us who did a lot of programming in other languages before JavaScript are probably familiar with classic data structures like the Map. A Map is a (typically) indexed collection of keys and their associated values. If you know the key, you can grab the value. C++ has collections objects, as does Java. JavaScript has not had a native Map until recently, but I've never really missed it. Why? Keep reading.

In many of the newest browsers and in Node 4, we can now use Maps. Their functionality should come as no surprise to anyone familiar with basic data structures found in other languages.

var m = new Map();

m.set("key1", "value1");
m.set("key2", "value2");

console.log(m.size); // 2

console.log(m.get("key1")); // "value1"
console.log(m.get("key3")); // undefined
console.log(m.has("key2")); // true
console.log(m.has("key4")); // false

But this is JavaScript! We needn't limit ourselves to just one type of key or value! Check this out:

var p = new Map();

// function as a value...not too strange:

p.set("f1", function(x) { return x*42; });

console.log(p.get("f1")(2)); // 84

// function as a key...a bit odd:

var w = function(z) {
    return z % 3;
};

p.set(w, "weird");

console.log(p.has(w)); // true
console.log(p.get(w)); // weird

Sure, it's perfectly legal code...but why? I know I'm not the world's smartest software engineer, but I cannot think of an example where putting a function as the key in a Map would make any sense. If you can think of one, please comment below.

Now we're having fun with Maps and we're all excited about JavaScript getting this great new data structure. But this is not a whole lot different from what we could always do in JavaScript with objects, since objects behave pretty much like Maps.

var h = {};

h["key1"] = "value1";
h["key2"] = "value2";
h["func1"] = function(t) { return t / 8; };

console.log(h["key1"]);      // value1
console.log(h["key3"]);      // undefined
console.log(h["func1"](16)); // 2
console.log(h.func1(32));    // 4

See? Pretty much the same as my first Map example up at the top. Fine, plain Objects have no size field...so I suppose that's one thing that Maps offer. There are also some differences is how iteration is handled. Consider the following example:

var myMap = new Map();
myMap.set("k1", 33);
myMap.set("k3", 55);

var myObj = {};
myObj["k1"] = 33;
myObj["k3"] = 55;

for (e of myMap) {
    console.log(e);    // the key and value as an array
    console.log(e[0]); // just the key
    console.log(e[1]); // just the value
}

for (e in myObj) {
    console.log(e);        // just the key
    console.log(myObj[e]); // the value
}

Iterating over the Map with for (e of myMap) gives you values for e that are 2-element arrays containing both the key and the value for each Map entry. Iterating over the Object with for (e in myObj) gives you values of e that are just the key.

I'm not going to tell you that JavaScript Maps are the greatest thing since sliced bread, but maybe sliced bread was never that big of a deal anyway. It's not like people didn't have knives. And speaking of bread...

Amphibian.com comic for 16 October 2015

Wednesday, October 7, 2015

Future JavaScript - Generator Comprehensions

A comprehension generator?
If you enjoyed my look ahead at a JavaScript feature of the future on Monday, then you're in luck. If not, well, please read the rest of this post anyway.

That's right, I'm going to talk about one more upcoming language feature likely to be part of the ECMAScript 7 specification. If you like generator functions and you like array comprehensions, you're going to love Generator Comprehensions!

Maybe.

Not just another weird mashup, Generator Comprehensions have a syntax almost identical to Array Comprehensions, but create simple generator functions based on iterable objects instead of new arrays. Generator functions, if you recall, are a new type of JavaScript function which exit and re-enter while maintaining their state. If your generator function needs are very simple, creating one with a comprehension may be desirable.

Take a look at the simplest of examples to understand how they work. Important note! Just like with Monday's Array Comprehension examples, these only work on Firefox 30+. Sorry Chrome/Node fans.

var data = [ 1, 2, 3, 4, 5 ];

var gen = ( for (n of data) n * 2 );

console.log(gen.next().value); // prints 2
console.log(gen.next().value); // prints 4
console.log(gen.next().value); // prints 6

The Generator Comprehension appears on line 3. It looks almost exactly like an array comprehension, but uses parentheses ( ) instead of square braces [ ] to delineate it. Inside the parentheses, it takes the form for (n of iterable) statement, where the iterable in this case is an array and the statement is multiplying n by 2. The generator created will yield the result of the statement with the next value of n each time it is invoked. It is equivalent to this code:

var data = [ 1, 2, 3, 4, 5 ];

function* doubler(a) {
    for (var i = 0; i < a.length; i++) {
        yield a[i] * 2;
    }
}

var gen = doubler(data);

console.log(gen.next().value); // prints 2
console.log(gen.next().value); // prints 4
console.log(gen.next().value); // prints 6

I suppose you'd have to agree that the comprehension version saves a few lines of code. And fewer lines means fewer chances to make a mistake, right? Maybe. But remember, if you overuse all this slick, super-short syntax, your code becomes less readable and therefore less maintainable. Trade-offs.

I should also mention that just like Array Comprehensions, the statement part of the expression can include an if. So if you wanted a generator that produced just the leap years from a given array of years, it might look like this:

var years = [ 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ];

var leapYears = ( for (y of years) if ( y % 4 == 0 && (y % 100 != 0 || (y % 100 == 0 && y % 400 == 0)) ) y );

console.log(leapYears.next().value); // prints 1996
console.log(leapYears.next().value); // prints 2000
console.log(leapYears.next().value); // prints 2004

Of course, cramming the leap year logic (divisible by 4 but not divisible by 100 unless also divisible by 400) into a single if statement just trades vertical code for horizontal code - and horizontal code really bothers me. Call me old-fashioned, but I like it when the lines are no more than 80 characters wide. But everyone is entitled to their own code style - unless you have to work on a team! Then you better do what's agreed upon by the group. Just sayin'.

Now for some commentary. While Generator Comprehensions are a fine way to create generators in a single line of code, I feel like the real power of generator functions is in having them encapsulate logic that can not (or should not) be expressed as a single line. If I just want to iterate over an array and even perform some basic translation of its values, I'm not sure that a Generator Comprehension would be my first choice. At the risk of sounding like a software dinosaur, there's nothing wrong with for loops when done correctly. Their intent is more clear, which makes maintenance less costly. I worry about those kinds of things because I'm a software engineer, not a hacker.

I'm also an author of frog comics, which means I worry about you clicking on the link below.

Amphibian.com comic for 7 October 2015

Monday, October 5, 2015

Future JavaScript - Array Comprehensions

I can't wait any longer!
I've spent a bit of time lately writing about new ES6 language features now available in Node 4, but JavaScript doesn't end there. The ECMAScript 7 specification will probably be out next year and should include even more wonderful things. I thought I'd take a look ahead today at the one I'm most excited about, Array Comprehensions.

An Array Comprehension, a feature already available in other languages, is just an easy way to create a new array from an existing one. JavaScript gives us other ways of doing that, such as map, but comprehensions provide a very tight and sensible syntax for a specific job.

Consider the following example. If you want to run this yourself, you'll need Firefox 30+. It is supported neither by other browsers nor Node at this time.

var a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

var b = [ for (n of a) if (n % 2 !== 0) n ];

console.log(b); // prints [ 1, 3, 5, 7, 9 ]

The array comprehension syntax can be see on line 3, creating a new array b containing just the odd numbers in array a. I like the syntax because the end caps [ ] are square braces, just like an array. Since a new array is the result of the expression, it makes sense. Inside the braces, it is very simple. You have for (n of a), which is the standard iteration syntax. The next part of the expression will be evaluated for each member of a, and for each evaluation n will be the current member. Whatever this expression is will be the value added to the created array. In this example, it will be only values of n which are odd. But consider this example.

var c = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

var d = [ for (n of c) n * n ];

console.log(d); // prints [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]

No ifs here, the new array will just contain the square of each number in the original array. But you don't even need to care about what's in the original array, technically speaking. Look at this.

var e = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

var f = [ for (n of e) "nothing" ];

console.log(f); // prints a lot of "nothing"

Rather useless, that one. But you could call a function instead...

function doSomething(p) {
    if (p % 2 === 0) {
        return p * p;
    } else {
        return p * 2;
    }
}

var x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

var y = [ for (n of x) doSomething(n) ];

console.log(y); // prints [ 2, 4, 6, 16, 10, 36, 14, 64, 18, 100 ]

Here's a catch, though. What if you want to zero-out the even numbers from the first array? So instead of returning a new array with just the odds, returning a new array with odds and zeros in place of the evens. You can't use the if...else syntax inside the braces.

var g = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

// this form does not work (invalid syntax):
var h = [ for (n of g) if (n % 2 !== 0) { n } else { 0 } ];

Instead, you have to either call a function or make it a single statement using the shorthand syntax.

var g = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

// this form works:
var h = [ for (n of g) (n % 2 !== 0 ? n : 0) ];
console.log(h); // prints [ 1, 0, 3, 0, 5, 0, 7, 0, 9, 0 ]

// so does this:
function zeroEvens(n) {
    if (n % 2 === 0) {
        return 0;
    } else {
        return n;
    }
}
var j = [ for (n of g) zeroEvens(n) ];
console.log(j); // prints [ 1, 0, 3, 0, 5, 0, 7, 0, 9, 0 ]

Lots of fun, am I right? Well, it's too bad we'll have to wait quite some time to have this much fun in production. Unless you are writing JavaScript for a 100% Firefox environment, you'll have to be patient. It's unclear when ES7 will be official and be supported by other browsers and some future version of Node. Maybe next year sometime? Anyway, this gives you something to look forward to. Like how you look forward to new Amphibian.com comics.

Amphibian.com comic for 5 October 2015

Wednesday, September 23, 2015

Template Strings - New in Node 4

Today on Amphibian.com, the frogs try to get past ad blockers by interleaving the text of ads with the rest of the text on their website. But since their website is their comic about their website (see Monday's topic - meta), there are problems.

Similarly, when you want to put the values of variables or other expressions in your JavaScript strings you probably do something like this:

var str1 = "some static text and " + someVar + " and some more text";

JavaScript Strings, circa 1905
A cool new ES6 feature now available in Node 4 is the Template String, which can make the above code a little nicer.

Template Strings are a new way of creating strings with embedded expressions. These expressions can be simply variables, formulas, or function calls. To make a Template String, use the back-tick ` (the thing that shares the key with ~ on an American English keyboard) instead of the regular tick ' or double-quote ". Inside, put expressions inside curly braces { } prefixed with a dollar sign $.

Here's an example.

var frogType = "Science";
var numFlies = 42;

console.log("The " + frogType + " frog caught " + numFlies + " flies");
console.log(`The ${frogType} frog caught ${numFlies} flies`);

Both messages print out exactly the same, but the second one, using a Template String, is shorter and looks nicer. I think it helps keep your code cleaner.

Another feature of Template Strings is that they can include literal new-lines. Look at this:

var str1 = "this is string 1\n" +
           "with two lines";

var str2 = `this is string 1
with two lines`;

console.log(str1);
console.log(str2);

console.log(str1 === str2); // prints true

The str2 variable is created by simply starting a new line in the middle of the string instead of embedding the \n. Also note that the two strings are equal when compared, despite being created in different ways. Personally, I'm not sold on this particular attribute of Template Strings. I think putting literal new-lines in there hurts the readability of the code, but you might not have a problem with it. Just throwing it out there!

Obviously, using this technique to include variable values in strings is useful. But you can put more complex expressions inside the braces.

var a = 2;
var b = 4;
console.log(`the product is ${a * b}`);

The code above prints the product of a and b by performing the multiplication in the Template String. But please note that the expression is only evaluated once, when the string is created. The following code exemplifies that:

var c = 3;
var d = 7;
var str3 = `the sum is ${c + d}`;

console.log(str3); // the sum is 10

d = 14;

console.log(str3); // the sum is 10

Changing the value of d after str3 has been created does not change the value of str3. Be careful, however, because the process of creating a Template String can change the values of your variables - just like if you did things the old-fashioned way.

var e = 1;
console.log(`the variable e = ${e++}`);

console.log(e); // prints 2

In the above code, printing out the Template String changed the value of e. Maybe this is what you want...maybe it's not. Be mindful.

But wait! There's more!

Template Strings also support tagging, meaning that they can be passed to a function which can modify their output. This feature is a bit unusual.

To use tagging, simply define a string processor function which should expect to receive as arguments
  1. a string array containing the "normal" parts of the Template String
  2. zero or more additional arguments, each representing an expression value
The tagging function should return a string, which is probably going to be some version of the data passed to it, but doesn't have to be related at all! Here's an example.

var test1 = 33;
var test2 = 44;

function tag(strings) {

    // print the static parts, in order
    strings.forEach(function(s) {
        console.log(s);
    });

    // print the expression values, if any
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            console.log(arguments[i]);
        }
    } else {
        console.log("no expressions!");
    }

    // this will be the tagged string value
    return "not the string you're looking for";

}

console.log(tag `Part 1 ${test1} part 2 ${test2}`);
console.log(tag `what? no expressions?`);

I've called my tagging function tag, but it can be anything you want. This first example just prints out the parts of the Template String so you can see how it works. It totally ignores the real contents of the Template String and returns nonsense. Those two calls to console.log both print the return value from tag. Probably not useful, but shows you what can be done. I honestly haven't thought of a legitimate use for tagging yet, but I might someday. Maybe you already know of one?

And there you have it. Template Strings, the good and the weird. I think the hardest part will be hitting that back-tick key. Not used to typing that one...

Amphibian.com comic for 23 September 2015

Monday, September 21, 2015

Symbols - New in Node 4

In continuing my discussions of new ES6 language features now available in Node 4, today I'm turning my attention to Symbols.

I'm not as sold on Symbols as I am on some of the other new features. What is a Symbol? A technical explanation is that Symbols are unique and immutable data types. Their purpose is to provide another way of making private properties on objects.

Ecmascript 6: The Future is Now!

Making Symbols is easy.

var sym1 = Symbol();
var sym2 = Symbol("whatnot");
var sym3 = Symbol("whatnot");

console.log(sym2 == sym3);  // false
console.log(sym2 === sym3); // false

The string parameter passed to Symbol() is optional and simply serves as a label. It doesn't mean anything to the Symbol itself. Making another Symbol with the same label doesn't mean the two Symbols are equal. Each Symbol created is unique.

So what does one do with these Symbols? I said that they're used for making private properties on objects, but how is that accomplished?

Let's start by defining the problem. When you have an object, JavaScript provides no protection of its properties. They can be redefined, or even removed! Consider this example.

var Frog = (function() {

    function Frog(type) {
        this.type = type;
    }

    Frog.prototype.getType = function() {
        return this.type;
    };

    return Frog;

}());

var f = new Frog("Science");
console.log(f.getType()); // prints Science

f.type = 27;
console.log(f.getType()); // prints 27

delete f.type;
console.log(f.getType()); // prints undefined

How can the frog type be made immutable outside of its own functions? Symbols are one possibility. Look at this code, slightly modified to use Symbols.

var Frog = (function() {

    var typeSymbol = Symbol("type");

    function Frog(type) {
        this[typeSymbol] = type;
    }

    Frog.prototype.getType = function() {
        return this[typeSymbol];
    };

    return Frog;

}());

var f = new Frog("CEO");
console.log(f.getType()); // prints CEO

console.log(f.type); // prints undefined

console.log(f["type"]); // prints undefined

var s = Symbol("type");
console.log(f[s]); // prints undefined

delete f.type;
console.log(f.getType()); // prints CEO

Instead of setting and accessing the frog type property internally using the dot notation (this.type), this code uses the bracket notation (this["type"]). BUT it uses the Symbol instead of the string "type" to make it inaccessible from outside. All attempts to read or delete the private type property will be unsuccessful. Even trying to do it with another Symbol fails, because Symbols made with the same label are not equivalent.

So that's Symbols. There are of course other ways to make fields private in JavaScript, such as using more closures or with Object.defineProperty. I haven't experienced any scenario where Symbols are really that much better than the previously available alternatives, but it's always nice to have more options.

I can't think of any way to tie this to the Amphibian.com comic for today, so here's the link to it without further comment.

Amphibian.com comic for 21 September 2015

Friday, September 18, 2015

Block Scoping - New in Node 4.0.0

Today wraps up "games week" on Amphibian.com. I had the frogs playing the lottery on Monday, Let's Make a Deal on Wednesday, and poker today. Since there's not much to discuss concerning poker being a game of skill or a game of chance, I'm back to discussing new JavaScript language features available in the recently released Node 4.0.0. (they've actually released 4.1.0 already but it's mostly just bug fixes).

So let's talk about Block Scoping!


This new ES6 feature gives you a new option for limiting the scope of declared variables to a block, statement, or expression. Just declare a variable with let instead of var and it won't be accessible to the entire function!

Here's an example that illustrates the point.

var x = 37;
if (x > 30) {
    let x = -1;
    let y = 900;
    console.log(x); // prints -1
    console.log(y); // prints 900
}
console.log(x); // prints 37
console.log(y); // prints undefined

if (x > 10) {
    var x = 5;
    var y = 777;
    console.log(x); // prints 5
    console.log(y); // prints 777
}
console.log(x); // prints 5
console.log(y); // prints 777

Inside the first if block, let x = -1 declares a block scoped variable x which is distinct from the global x variable declared on the first line. Changing it inside the block has no effect outside the block. By contrast, the second if block declares var x = 5, which isn't really much of a declaration at all. The x variable already in scope simply has its value reassigned. Once outside the block, it still has the value give it inside the block.

Also note the behavior of the y variable. Declared using let inside the first if block, it is undefined when used outside. But declaring it using var inside the second if block makes it global.

Declaring variables with let also works in for loops.

var i = 50;
for (let i = 0; i < 5; i++) {
    console.log(i); // prints 0 through 4
}
console.log(i); // prints 50

for (var j = 0; j < 5; j++) {
    console.log(j); // prints 0 through 4
}
console.log(j); // prints 5

The first loop, using let, prints the value of the variable i which is scoped to just the for loop. Outside of the loop, i still refers to the global variable. The second loop declares j with var and so j becomes available outside of the loop.

Making good use of let for variable declaration can make your code cleaner and lead to fewer bugs.

One final thing to note, however. While block scoping is available in Node 4.0.0+ it only works in strict mode. That means either launch node with the --use_strict flag or put
"use strict";
at the top of your source file. But you're probably using strict mode already, right?

Good. Now enjoy today's comic.

Amphibian.com comic for 18 September 2015

Wednesday, September 9, 2015

Arrow Functions - New in Node 4.0.0

New! Improved! Skipping Numbers!
In news much more important than whatever my frogs did today, Node 4.0.0 was just released. If you're confused by that version number, you're in good company. I thought we were just on version 0.12.7. Did 1.x.x through 3.x.x end up in the same place as Windows 9?

No, no. Node 4.0.0 represents the merge of the Node and Io.js baselines. Io.js split off Node back in December but the two projects have settled their differences and come back together. This means Node now has support for a bunch of new features from the JavaScript ECMA-262 specification, like promises and arrow functions.

I've talked about promises before, but arrow functions...those are interesting. They are basically an even shorter way of expressing anonymous functions.

Consider this example. Let's say you had an array of the first 10 prime numbers and you wanted to add them all up. In a prior version of Node, you could reduce the array by supplying a simple anonymous function as the argument to reduce.

var arr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

var sum = arr.reduce(function(a, b) {
    return a + b;
});

Not bad. I'm sure we've all done simple anonymous functions like that before. But with an arrow function, the same process looks like this:

var arr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29];

var sum = arr.reduce((a, b) => a + b);

A bit shorter, and it looks nicer as a single line. So what does that syntax really mean?

The arrow function notation basically says execute one or more statements on the right side of the arrow using one or more arguments from the left side of the arrow. If there is only one statement, the return is implicit (above, the statement a + b is equivalent to return a + b). The arrow, of course, is just an equals sign followed by a greater-than sign. It's really just a more concise way of expressing a function which you may find appealing in certain situations.

// multiple args, one statement
var f = (a, b, c) => c ? a + b : a * b;
f(3, 6, false); // equals 18
f(3, 6, true);  // equals 9

// one arg, multiple statements
var g = a => { var b = a * a; var c = a / 2; return b + c };
g(44); // equals 1958
g(22); // equals 495

Nice, huh? There's a lot more new with Node 4.0.0 as well, so you might want to check it out. I'll probably be migrating Amphibian.com to it within the next few weeks. I expect a painless transition, but we'll see. In the mean time, continue to enjoy the comics served up by a prior version of Node.

Amphibian.com comic for 9 September 2015

Wednesday, August 19, 2015

Loop or Map?

If I use map, can I fold it
back up when I'm done?
Here's something that has been coming up a lot lately: when processing an Array in JavaScript, should I use a for loop or the map function?

If you've looked at my code you'll notice a distinct lack of map. I don't use it very much. I honestly don't think I do a lot of Array iteration in general, but when I do, I typically just write a for loop. Good? Bad? Does it matter?

Let's look at a typical scenario in my comic code...taking an array of results from a database query and turning them into an array of data to return.

pool.query('SELECT filename, type FROM comic_img', function(err, rows) {

    var data = [];

    if (rows.length > 0) {
        for (var i = 0; i < rows.length; i++) {
            data.push({
                name: rows[i].filename,
                mimeType: rows[i].type
            });
        }
    }

}

That's the method using a for loop. Pretty straightforward. Make an empty array for the return data, loop over the rows of the query results, pushing new objects to the data array that are made from parts of the objects in the rows array.

Now let's do the same thing with the map function.

pool.query('SELECT filename, type FROM comic_img', function(err, rows) {

    var data = rows.map(function(val) {
        return {
            name: val.filename,
            mimeType: val.type
        };
    });

}

It's a little more compact, without the need for the definition and incrementation of i, comparison with rows.length, or access to the object by index. You could argue that the map version is more readable, which is nice. I do like my code to be very readable.

What you can't say is that the map version is any faster. Internally, map has to be doing a loop plus other stuff, which will undoubtedly make it slightly less performant than the basic for loop. The speed difference won't be that much different, so in most cases you shouldn't be too concerned.

There is another benefit to the map coding style. When you already have your code structured this way, it's easy to add asynchronicity. What if you just want the array processed but don't care about the order? Remember when I talked about the Node async module? It's simple to turn the plain map code into asynchronous map code:

var async = require('async');

var rows = getSomeArray();

async.map(rows, function(val, callback) {
    callback(null, {
        name: val.filename,
        mimeType: val.type
    });
}, function(err, data) {
    console.log(data);
    // do whatever you want with the resulting data
});

Instead of the processing function returning the new data, it passes it as the second argument (first would be any error that occurred) to its supplied callback function. And instead of having map return the new array, async has you specify a third argument which is a callback function. When everything is done, it gets called with the results. Sure, in this example there's not really any point to making the processing asynchronous, but if your processing involves anything with the file system or a web service call you have a perfect candidate.

That would be a lot more difficult to do with a for loop. You'd actually need several for loops. And probably some recursion. And magic. Just forget about it.

The moral of the story is, map is probably better in most cases than for loops. It's more readable and gives you a good foundation for expansion in the future. I'll try to do better at it myself. I'll also try to make better comics, but for today this is all you get:

Amphibian.com comic for 19 August 2015

Friday, August 14, 2015

Integration of the Frog Soccer Game

After getting some testers to try out my frog soccer game (mostly children) and making a few tweaks to the physics of the frogs and the ball, I decided that it was good enough to replace the old 404 page on Amphibian.com. Not that I'm completely done with it, but it's good enough that if someone finds it I'm not too upset.

It turns out that was easier said than done.

I have been keeping the source code for the game in its own repository separate from the comic repo. I want to keep the two mostly separate so that I can update the game independently of the comic. How, then, should I go about having them combined from a user perspective when visiting the site? It might not be the best, but I came up with this plan...

First, I moved the variables that control the width and height of the game canvas out of the game2.js file. I put them inside a script tag in the index.html.

<!DOCTYPE html>
<html>
<head>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">

    <title>Froggy 404</title>

    <link rel="stylesheet" type="text/css" href="css/style.css"/>

    <script>
    
    var width = window.innerWidth;
    var height = window.innerHeight;

    </script>
    <script src="//ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script>
    <script src="js/phaser.min.js"></script>
    <script src="js/game2.js"></script>
    
</head>
<body>

<p>This is the 404 Page for Amphibian.com</p>

<div id="gameArea"></div>

<p>Thanks for playing!</p>
  
</body>
</html>

As you can see, I also added a div with the id "gameArea" to the HTML so that I can explicitly place the canvas when the Phaser Game object is created.

var game = new Phaser.Game(width, height, Phaser.AUTO, "gameArea", {
    preload: preload,
    create: create,
    update: update,
    render: render
});

I made these changes so that I could include the game2.js file from a totally different HTML page and the game will still work.

The next step was to create a symbolic link in the main directory of the comic to the public directory of the 404-page game. I keep clones of both repositories under the /projects directory on my Ubuntu Linux server.
$ cd /projects/comic
$ ln -s soccer /projects/comic-404/public
Now my comic app can peer into the public folder of the 404-page app using the alias "soccer." This allows me access to the JavaScript, audio, and images as if they were part of the comic without them actually being part of the comic. I also added /soccer to the .gitignore file in the comic's main directory - so git doesn't think soccer is actually part of this repo.

Now I changed the code for the comic app. I set up a special route for the game under the path /404. If http://amphibian.com/404/ is requested, I respond with a special Jade template named "missing." Any requests for other files under that path, such as http://amphibian.com/404/js/game2.js for example, will be served as static content out of the "soccer" path on disk - which is the symbolic link to the public directory of the game's repository.

var soccerRoutes = express.Router();

soccerRoutes.get("/", function(req, res, next) {

    res.render("missing", {
        title: "404 Frog Soccer"
    });

});

soccerRoutes.use(express.static("soccer"));

app.use("/404", soccerRoutes);

The "missing" template has the same style, header, and footer as the rest of Amphibian.com but also includes the "gameArea" div and sets the width and height just like the index.html file in the 404 app does. Now the code in game2.js doesn't care which page is actually including it and works both ways! I can continue to update both apps independently as well. Go to http://amphibian.com/404/ to see it for yourself.

That was my solution. It works well enough, but if you have any better suggestions please leave them in the comments below! Thanks, and don't forget to read today's comic. You won't want to hit the Undo button!

Amphibian.com comic for 14 August 2015

Wednesday, August 12, 2015

Using Facebook's Graph API to Count Shares

Have you shared today's comic yet? Getting it shared at least 100 times on Facebook is the only way to unlock the action in the last frame. Well, it also has to be Wednesday. So share it 100 times today or wait until next week to try again.
Bombs don't look like this in real life.
This depiction is illogical.

The joke is that the frogs have discovered a logic bomb in a computer, and logic bombs only go off when their criteria are met. The criteria of this particular one include Facebook shares and the day of the week. Really it's designed to get me lots of attention on social media, but there is a joke in it.

Now to the good part...how does it work? The day-of-the-week part is easy, but checking the number of Facebook shares was slightly more involved. I used the Facebook Graph API.

There is a ton of stuff you can do with it, but for now I'm keeping it simple. I wanted to be able to check how many shares a given URL has. And you ask yourself, "Why doesn't he just look at that little number down below every comic?" Well, I'll tell you. That's a Facebook widget that functions by embedding an iframe in the page. I can't really check what it's doing from my own code. I had to write some server-side code to interface directly with Facebook.

Since share information is public, you can access it just by hitting a Facebook URI with any valid access token.

https://graph.facebook.com/v2.4/?access_token=<your-token>&id=<object-id>

The object id is just the URL that you want to check shares on. For me, it's something like http://amphibian.com/205. The tricky part is getting an access token. The easiest way to do it is to create a Facebook App and use the permanent access token associated with it. Sign up as a Facebook developer, and then create a new web app. After you have a web app set up, go to the Tools & Support menu and select Access Token Tool. You should then see a pair of tokens for your app, a User Token and an App Token. The App Token is the one you want because it never expires.

DO NOT share these tokens with anyone, or put them in client-side code! DO NOT! It will give anyone permission to perform actions as your application. I put the App Token in a server-side config file that is NOT committed to source control (at least not in a public repo).

Once you have both an access token and an object id (of something that's been shared at least once), hit the URL and you should get a JSON response.

Something like this:

{
  "og_object": {
    "id": "1128024717211703",
    "description": "Amphibian.com webcomic for Monday, 10 August 2015",
    "title": "Crowdfunding",
    "type": "website",
    "updated_time": "2015-08-10T08:18:03+0000",
    "url": "http://amphibian.com/205"
  },
  "share": {
    "comment_count": 0,
    "share_count": 12
  },
  "id": "http://amphibian.com/205"
}

I just parse that response and get the number of shares. I am doing this from a Node application, and just like when I used the Imgflip API to make memes, I use the convenient request module:

app.get("/shares/:id", function(req, res, next) {

    var comic = req.params.id;
    var token = "your-token-here";

    request({
        uri : "https://graph.facebook.com/v2.4/",
        qs : {
            access_token : token,
            id : "http://amphibian.com/" + comic
        }
    }, function(error, response, body) {

        if (!error && response.statusCode == 200) {

            var data = JSON.parse(body);

            res.setHeader("Content-Type", "application/json");
            res.send({
                id : data.id,
                shares : data.share.share_count
            });

        } else {
            next(error);
        }

    });

});

Again, I must stress that this code has to be done on the server side, since you don't want to give clients access to your App Token. When the client JavaScript has to check if it's ok to set off the cartoon bomb, I access a URL on my server that essentially proxies the request to Facebook. The code example above sets up a route /shares/:id that will give the share data for any comic to a client without exposing my App Token to the world.

Not too difficult. I just hope my plan is successful and the comic gets lots of shares. Trust me, it's worth it. Go on, check it out. It's also got a Zero Wing reference in there (which you can see before it's shared).

Amphibian.com comic for 12 August 2015

Friday, August 7, 2015

Custom Fonts with Phaser

It's been a while, but I'm back working on my 404-page game (full source code here) built with Phaser. I wanted to add some game text like scores and a title. Fortunately, Phaser makes this fairly simple.

Using the Phaser.Text object, you can render text to the game canvas without much difficulty.

var myScore = 0;
var opScore = 0;

var scoreText1 = game.add.text(20, 10, "Home: " + myScore);
scoreText1.fixedToCamera = true;

var scoreText2 = game.add.text(1060, 10, " Away: " + opScore);
scoreText2.fixedToCamera = true;

The code above creates two text objects that display the team scores, with the text fixed to a certain location on the screen. This means that as the camera moves around, the text won't.

Putting text on a canvas is not trival, but Phaser makes it appear as if it were. To do the magic, Phaser is actually rendering the text to a hidden canvas and using that canvas to get the bitmap image to display in your main game canvas. The catch? Any font you use has to be already loaded and ready in the browser. Not a big deal if you want plain, boring text. But I wanted to use my comic's go-to font Sniglet.

Sniglet is available free from Google Fonts, so I include it on many of my pages the typical way...

<link href='http://fonts.googleapis.com/css?family=Sniglet' rel='stylesheet' type='text/css'>

That doesn't help me in Phaser. Because the font load happens asynchronously, I need to make sure that the font is fully loaded before I try to render any text with it. That's where the Typekit Web Font Loader comes in. Co-developed by Google and Typekit, it gives developers more control over web fonts, and allows me to control the flow of the game setup based on when the font is loaded.

I was a little confused by the Google Fonts integration example provided by Phaser. This is what their example does:

// The Google WebFont Loader will look for this object,
//    so create it before loading the script.
WebFontConfig = {

    //  'active' means all requested fonts have finished loading
    //  We set a 1 second delay before calling 'createText'.
    //  For some reason if we don't the browser cannot render the text the first time it's created.
    active: function() { 
        game.time.events.add(Phaser.Timer.SECOND, createText, this);
    },

    //  The Google Fonts we want to load (specify as many as you like in the array)
    google: {
        families: ["Sniglet"]
    }

};
 
function preload() {

    // Load the Google WebFont Loader script
    game.load.script("webfont", "//ajax.googleapis.com/ajax/libs/webfont/1.4.7/webfont.js");

    // ... load other stuff ...

}

function createText() {

    // ... create text objects here ...

}

I don't like how Phaser's examples just throw the code out there with no explanations. What's going on is a WebFontConfig object is being created for the Web Font Loader to use when it does it's thing. In this example, two fields are specified in the object: active and google. The google field is an object that tells Web Font Loader to load the specified font families from Google Web Fonts. I am only loading one, Sniglet. The active field specifies a function that will be called when the fonts are fully loaded and ready. In Phaser's example, that function waits one second and then calls the createText function. In the game preload, the Web Font Loader script is dynamically injected into the page which kicks off the loading. When it's all done, active gets called, waits one second and calls createText. Text then appears in the game.

But hold on. Look at the comment above active. That's right out of Phaser's example. "For some reason..."???? Comments like that just feed my curiosity. Can I figure it out? Can I make it better?

Of course I tried getting rid of the one-second delay to see what would happen. What happened was that createText was called too fast (before the game's create function), and the text ended up below my ground tiles. The font was fine, but you couldn't see it. Adding the delay back in just ensured that everything else was done before the text was added on top of everything else. So their example works, but that's some weird control flow if you ask me.

I tried taking a slightly different approach. I include the Web Font Loader script explicitly in my HTML and then do the following:

var wfconfig = {

    active: function() { 
        console.log("font loaded");
        init();
    },

    google: {
        families: ['Sniglet']
    }

};

WebFont.load(wfconfig);

// ...

var init = function () {

    // ... variables declared and whatnot ...

    var game = new Phaser.Game(width, height, Phaser.AUTO, "test", {
        preload: preload,
        create: create,
        update: update,
        render: render
    });

    function preload() {
        // ... nothing new ...
    }

    function create() {

        // ... create all the other stuff ...

        scoreText1 = game.add.text(20, 10, "Home: " + myScore);
        scoreText1.fixedToCamera = true;

        // ... and so on, and so on ...

    }

    // ... all the other stuff

}

As soon as the page is ready, I call WebFont.load(wfconfig). Then in the active function, I make the call to set up the game. In my game's preload I don't have to do anything special, and I just create the text objects after all the other game objects to ensure that they are on top (in my game's create function). I shouldn't have to worry about whether or not the font is loaded yet because I put off starting the whole game setup process until after I was sure that it was loaded.

Seemed to work for me. I'm sharing this so that, at least for today, I have not subtracted from the sum of human knowledge. Huh? Read the comic.

Amphibian.com comic for 7 August 2015

Friday, July 31, 2015

Make Memes via API Calls

In today's comic the frogs are recycling pictures into memes, and by clicking on the meme in the last frame you can create your own frog meme. You just type in your own text and your personalized meme appears. You can even share it.

I don't want to get into a debate about how the sharing of memes has destroyed what remains of our humanity - it's just a comic about frogs. The interesting thing is how I was able to find a meme generation API that I could work with to make this comic possible.

My first attempt at this used memegenerator.net. It's a very popular meme site. They have a JSON API and there are even some modules for Node.js that interface with it. That all sounded good. I tried out the node-meme module and it worked - for all the read methods. Once I tried to create a meme with it I was informed by an error code that I needed valid login credentials.

No problem! I'll just register for an account.

Nope.
Or not. Apparently, account registration has been unavailable for quite some time. All attempts at it result in a rather unintelligible error message. There goes that plan!

After some more searching I found Imgflip.com. They have both a meme-generation API and functioning account registration! Yeah!

To make the comic work the way I intended, I needed to make all the memes from my server and then just update the browser with the Imgflip URL. This prevents everyone who uses the comic from having to get their own account, but it makes things a little more complicated for me. I essentially had to set up a meme-generation proxy. Your browser POSTs data to my server, my server POSTs data to Imgflip, Imgflip generates a meme and tells my server the URL, and finally my server tells your browser the URL.

This also required me to do something I haven't done a lot of before - use the Node http client. Sure, I've done simple things with it in the past, but the out-of-the-box features make it a bit difficult to use when you want to access a REST web service.


So I also started using the request module. It greatly simplifies working with HTTP(S) requests in Node. Here is an example of how I use it to interact with Imgflip's API:

var request = require("request");

var formData = {
    template_id : "41754803",
    username : "user",
    password : "passwd",
    text0 : "i look displeased...",
    text1 : "but i have no idea what's going on"
};

request.post("https://api.imgflip.com/caption_image", {
    form : formData
}, function(error, response, body) {

    var meme = JSON.parse(body);

    if (!error && response.statusCode == 200) {
        console.log(meme.data.url);
    }

});

Simple, right? The first parameter to request.post is the URL.

The second is what to POST. In this case, I want to POST a form, specifying the form data as an object. Imgflip only accepts form data as input, and every POST must include your username and password. You get those by registering on their site. The template_id form field is the id number for the meme image you want to use. If you upload your own meme template images, you can find the id numbers on template details page linked from your account. The text0 field is the text for the top of the image, and text1 is for the bottom.

The third parameter is the callback function for when the POST completes. This function gets an error (if there was one), the response object for checking the status code (and other stuff if you want), and the body of the response. In the case of the Imgflip web service, I know the body will be JSON. In this example I just log the meme image URL.

That is much simpler than doing it the purely native way. I recommend the request module if you need to do any kind of REST API access and there's no custom client available.

Now the fun begins: frog memes for everyone!

Amphibian.com comic for 31 July 2015