Friday, October 31, 2014

Give Me Some Sugar

Since today is the day when children typically put on costumes and go around to their neighbors' houses to ask for candy, I thought I'd take a minute to let everyone know about my favorite candies.

Milkfuls
I love Milkfuls. Like so many other things (why did they take away Dunkin Donuts Cereal???), they are no longer available. At least not in the United States. I think they might still be sold in other parts of the world.

Werther's Original
Werther's Original is another one that I really enjoy. Thankfully, these are still around. I used to eat these all the time at my grandparents' house.

They're not in stores this time of the year, but around Easter I buy a lot of Cadbury Mini Eggs. I absolutely hate the Cream Eggs, but the Mini Eggs are just chocolate with a hard candy shell. Like an M&M I suppose, but with more chocolate and the shell tastes better.

I don't really love chocolate. I like it, but rarely eat it by itself. Reese's Peanut Butter Cups are good, but the small size Reese's Eggs they have around Easter (again, Easter beats Halloween for candy) are the best. The chocolate-to-peanut-butter ratio is perfect in those - more so than any other variety.
Stock up on these at Easter!
Snickers bars are okay, and just about the only American candy bars I will eat. I have to say that my favorite candy bar is the Nestle Lion Bar. I got hooked on those things when I was in the U.K. back in 1995. I buy several whenever I find them anywhere in the United States, which is rare. Also, the U.K. Kit Kat is far superior to the U.S. version due to the use of Nestle chocolate in their European production.
My all-time favorite
Are you hungry now? Put on a costume and go knock on your neighbor's door.

Amphibian.com comic for 31 October 2014

Wednesday, October 29, 2014

Open Source Clipart

As you may already know, I create the artwork for Amphibian.com using Inkscape. All the frogs, trees, rocks, grass, and chef puppets are Scalable Vector Graphics. It's an interesting medium in which to work. It initially appealed to me because even when I drew things by hand they were always made out of simple geometric shapes.

I occasionally need a graphic of something that I am not good enough to draw myself (yet). When I do, I usually go to OpenClipart.org. Everything they have there is in SVG format and in the Public Domain. It's open-source clipart.

While I do need to maintain copyright control over my frogs, I also like to contribute back to the community. As such, I add some of the drawings I make of the accessories in the comic to OpenClipart.org from time to time.

Check it out next time you need a drawing for a presentation or web page.

Amphibian.com comic for 29 October 2014

Monday, October 27, 2014

Beware the Draggin'

One interesting thing I learned while developing 2-Player Solitaire is that there is no way to programatically cancel a drag in jQuery UI. Once a user starts dragging something, the drag has to finish. That means you have to process any drop events that might occur.

Making something draggable is really easy. Making something a drop target is really easy.

<!doctype html>

<html lang="en">
<head>
    <meta charset="utf-8">
</head>

<body>
    <div id="draggable">What a drag.</div>
    <div id="dropzone">Drop here.</div>
</body>

<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<script>

$("#draggable").draggable();
$("#dropzone").droppable();

</script>

</html>

I was in the unfortunate position of having a virtual card table that allowed 2 players to go after the same cards to drag them around. As soon as one person started dragging, the server would place a lock on the card so that no one else could start dragging it. However, since both clients could start the drag and send the "drag start" event to the server simultaneously, one of the draggers would have to lose. The server would lock on one of the events and then asynchronously send a message to the other telling it to stop dragging. That last part turned out to be difficult.

The folks that make jQuery won't provide a "cancel" method. They have some good reasons for doing so, which you can read about on the feature request ticket. In general I agree with their reasoning, but I was trying to create a very non-standard UI. It had to give the impression that the other player just grabbed the card before you did, instead of letting you both drag it around independently and then tell one of you at the end that you were wasting your time.

What did I do? I learned that if you return false from a draggable's start or drag event handlers, it will stop the drag. In the case of the start handler, the drag never really gets to begin. Still, that didn't help me because I couldn't perform a synchronous check with the sever in that handler to see if it should allow the drag. Returning false from the drag event's handler stops the drag, but still fires the drop event if the item being dragged ends up over a droppable area. Since my intent was to make it as if the drag never really happened, that side effect was problematic.

$("#draggable").draggable({
    start: function(event, ui) {
        var ok = true; // determine if dragging is ok to start
        return ok;
    },
    drag: function(event, ui) {
        var ok = true; // determine if dragging should continue
        return ok;
    }
});

It wasn't perfect, but it was my only option. If a player started dragging a card at the same time as the other player, one of them would get shut down by the server. The server would emit an "abort drag" event to the client (via Socket.io) and the card would get a flag set on it, telling the drag event handler function that it needed to return false. The drop event handler also checked this flag, and after clearing the flag, returned immediately instead of doing the normal drop stuff. This was enough to provide the illusion that the drag never really started. And it works in my case because I don't specify a handler for the droppable's drop event - if I did, and the drag was canceled while over that area, the drop event would still be fired there. That might produce more unwanted side effects.

In the following example, I set a timer to cancel the drag 2 seconds after you start it. This provides a good example of an asynchronous even causing the cancel. Drag and drop in under 2 seconds, and you see the "normal" path. Hold on to the draggable for more than 2 seconds, and it will get cancelled on you.

$("#draggable").draggable({
    start: function(event, ui) {
        var d = this;
        d.cancelDrag = false;
        window.setTimeout(function() {
            d.cancelDrag = true;
        }, 2000);
    },
    drag: function(event, ui) {
        if (this.cancelDrag) {
            console.log("stopping the drag!");
            return false;
        }
    },
    stop: function(event, ui) {
        if (this.cancelDrag) {
            console.log("drag was cancelled, don't do anything");
            this.cancelDrag = false;
            return;
        }
        console.log("drag was completed normally");
        // do other stuff here...
    }
});

If this method doesn't suit you, there is another possibility. In my research, I came across this very interesting way to allow a drag to be canceled without firing any events on drop targets. It works by programmatically generating a mouse event which is then dispatched to the window. It tricks jQuery into thinking that the user released the mouse button (thereby stopping the drag) while the cursor was in an impossible location (thereby not over any droppable targets). In the following example, the drag is aborted by pressing the ESC key (note the keydown event checking for keyCode == 27) but you could really do the same thing from anywhere.

$( window ).keydown( function( e ){
    if( e.keyCode == 27 ) {
        var mouseMoveEvent = document.createEvent("MouseEvents");
        var offScreen = -50000;

        mouseMoveEvent.initMouseEvent(
            "mousemove", //event type : click, mousedown, mouseup, mouseover, etc.
            true, //canBubble
            false, //cancelable
            window, //event's AbstractView : should be window
            1, // detail : Event's mouse click count
            offScreen, // screenX
            offScreen, // screenY
            offScreen, // clientX
            offScreen, // clientY
            false, // ctrlKey
            false, // altKey
            false, // shiftKey
            false, // metaKey
            0, // button : 0 = click, 1 = middle button, 2 = right button
            null // relatedTarget : Only used with some event types (e.g. mouseover and mouseout).
                 // In other cases, pass null.
        );

        // Move the mouse pointer off screen so it won't be hovering a droppable
        document.dispatchEvent(mouseMoveEvent);

        // This is jQuery speak for:
        // for all ui-draggable elements who have an active draggable plugin, that
        var dragged = $(".ui-draggable:data(draggable)")
            // either are ui-draggable-dragging, or, that have a helper that is ui-draggable-dragging
            .filter(function(){return $(".ui-draggable-dragging").is($(this).add(($(this).data("draggable") || {}).helper))});

        // We need to restore this later
        var origRevertDuration = dragged.draggable("option", "revertDuration");
        var origRevertValue = dragged.draggable("option", "revert");

        dragged
            // their drag is being reverted
            .draggable("option", "revert", true)
            // no revert animation
            .draggable("option", "revertDuration", 0)
            // and the drag is forcefully ended
            .trigger("mouseup")
            // restore revert animation settings
            .draggable("option", "revertDuration", origRevertDuration)
            // restore revert value
            .draggable("option", "revert", origRevertValue);
    }
}

Cool idea. I can't take credit for that one, it was written by "eleotlecram" who I know only by his Stack Overflow profile page.

Happy dragging!

Amphibian.com comic for 27 October 2014

Friday, October 24, 2014

Corn: The First GMO?

Do you like corn? Popcorn? Sweet corn? Candy corn? Okay, that one's not really corn, but it's probably made with high-fructose corn syrup.

It may surprise you to learn that corn, the grain produced more than any other grain on this planet, was invented by humans. It would not exist on its own.

But it wasn't created in a lab by some mad scientist. Thousands of years ago, the indigenous peoples of Mesoamerica created it the old fashioned way - selective breeding. They certainly weren't mad. They were probably fairly happy. By cultivating a wild grass called Teosinte and selecting plants for certain qualities, those early Mexican farmers made the plant we know today as corn. 

Teosinte (left) and modern corn (right).
The middle is a hybrid of them both.
Photo by John Doebley.
So in a way, we have been creating Genetically Modified Organisms since we started farming. By cross-breeding different plants and selecting the ones with the most desirable traits for more cultivation, each generation of food crop was genetically different from the previous one. In a fairly short time, corn went from a plant that could produce one small ear per stalk to a plant that produces many foot-long ears per stalk. That's almost as weird as making fish that glow, and didn't require any test tubes or Erlenmeyer flasks.

And corn isn't the only plant to get this treatment! Consider Brassica oleracea. Humans took that plant, wild mustard, and turned it into cabbage, broccoli, kale, Brussels sprouts, collard greens, and kohlrabi. Yes, that's right. broccoli and kale are the same plant! Same species. Brassica oleracea. Totally blew my mind when I first learned this.

These are the kinds of things that influence my web comic. Today's was actually a reproduction of one I created back in 2001. It was probably the last one I did before re-launching this year. Back then, there was only one frog, and he only sometimes wore a lab coat. But he did try to analyze the genetic makeup of marshmallows. As far as I know, those were only domesticated starting in 1934 and their genome has yet to be sequenced.

Wednesday, October 22, 2014

Socket.io with Express

Today I introduced the world to 2-player Solitaire. It was the joke in today's comic, but I thought that it might work in real life too. At the very least, it helps add dimension to the joke.

In it, you and a friend are looking at the same card table. For each valid card placement, you get 1 point. Your goal is to put the cards on valid placements before your opponent does and thereby score the most points.

I've been working on it for about 3 weeks now, which is why I haven't had time to put much code in this blog. But now that it's ready (don't hesitate to send a bug report if you find anything weird) I have time to talk about different parts of it on a technical level.

It is a web application, using just HTML5 and JavaScript. It is playable on both mobile devices and your desktop. Since the main premise is a shared game board, I used Node and Socket.io to share the real-time game data between two web browser clients. I've been using Socket.io for years now, but this was only the second time I've used the 1.0 release combined with the Express framework. The first time I struggled with some things, so I thought I'd share the basic application outline that I came up with to make your life easier.

I'm using Express 4.8.7 and Socket.io 1.0.6 in this project. To set up your application to handle both "normal" HTTP traffic and the various Socket.io communication types, you have to deviate slightly from a typical Node/Express setup.

var express = require("express");
var http = require("http");

var app = express();
var server = http.Server(app);
var io = require("socket.io")(server);

//------------ Socket.io stuff

io.on("connection", function(socket) {
 
    // set up handlers for different events here
    socket.on("some_event", function(data) {
        // do something
    });

});

//------------ web application routes

app.get("/some/path", function(req, res, next) {
 
    res.send("some response");
 
});

// ------------ start the listening

var srv = server.listen(5000, function() {
    console.log("listening on port %d", srv.address().port);
});

The main difference between this configuration and a more typical Express app is what you see on line 4. You have to require the "http" module explicitly, and use it to create a Server instance using your Express app instance. You then pass that Server to Socket.io as I do on line 6.

After that, use your io and app objects to set up your application behavior via event handlers and routes. At the end, start your Server listening. Note that on line 29, it is the http server instance you use to start the listening instead of the Express app object.

Try that, and you're off to a good start. As always, the source code for the entire game is available on GitHub. Check it out if you want to see how I did everything else, or keep reading here and I'll talk about other parts of it soon.

Amphibian.com comic for 22 October 2014

Monday, October 20, 2014

Follow the Scrip

Today's Amphibian.com comic represents the intersection of three very different issues. A trivium, if you will. That's the singular form of trivia. And trivia are 3-way intersections. Seriously, "trivia" is a place where three roads meet. It's Latin. Tri = 3, Via = road.

So what were these three things that came together in my mind and inspired me to create such a comic?

One was the recent surge in cryptocurrencies. It's like Bitcoin got some attention in the mainstream-ish media and then everybody was coming up with their own Whatevercoin. Litecoin. Dogecoin. Peercoin. Darkcoin. There's even Pandacoin. Why not Frogcoin? You get the idea. Everybody was making up coins. Maybe they felt like since they missed the boat on Bitcoin, they should start mining something else (or maybe everything else) just in case one of the others ends up being the winner. I guess it could happen. It happens with other things. For example, Google wasn't the first search engine, just the best. Sorry Bing.

The second thing was companies paying employees with debit cards instead of checks or direct deposit into checking accounts. It happened back in 2013 in a couple places and it really troubled me. Basically, workers were getting paid with those Visa pre-paid cards that you can use like credit cards to buy things. The problem was that there were sometimes fees associated with their use, and it can be tricky to spend 100% of those things. If you've ever had one you know what I mean. Workers were basically being cheated out of some money. The reasons that employers were doing this seemed a little shady. Some lawsuits were filed, and thankfully the government ruled that employers can't require you to get paid that way. They still have to give you the option of regular pay. I'm glad they did that, because I was concerned with the natural progression of the idea if it had been left unchecked.

And by progression, I mean regression. The third thing, which is tangential to the second, is the concept of company scrip. I thought, "what if Wal-Mart decided to pay its employees with Wal-Mart gift cards?" It seemed like a real possibility. Then I found out that it actually happened! At least in Mexico. Fortunately, the Mexican Supreme Court put a stop to it. But what if they try it someday in the United States? Then we'll be back in the days of the mining companies paying their employees in fake money that was only good at the company stores, which sold everything with huge mark-ups and kept the employees constantly indebted to the company. That practice ended many years ago, and I do not want to see it return. But wait, mining companies? That ties back to the cryptocurrency thing, since people "mine" for the coins! Whenever I find a loop like that, I know there has to be at least one comic I can make out of it.


Therefore, the end result of my ponderings on these issues was the comic in which frogs are working in a cryptocurrency mine and getting paid in a different and more obscure cryptocurrency which is only good in their company store. I'm fairly certain that Merle Travis would write a song about that exact scenario if he were still alive. It would probably be titled Sixteen Gigabytes.

Amphibian.com comic for 20 October 2014

Friday, October 17, 2014

ANSI, the Other 8-Bit Art

Despite the fact that I have 2 full-size old-school arcade games in my house (Dig Dug and Burgertime) and I do enjoy Minecraft, I am not a huge fan of 8-bit art. Back in 1982 when Burgertime was new, big-pixel games were the only games. Now people draw their game art in that style that just because they like it. I think some of the new games drawn like that look really good, and I am really impressed with artists' abilities to work in that style. But it's just not my favorite game art style.

If you haven't heard, 8-bit art (and also music) refers to a style reminiscent of the video games played on 3rd-generation home consoles such as the Nintendo Entertainment System, Sega Master System, and the Atari 7800. The term "8-bit" refers to the processors in those consoles. The number of bits became a selling point, and the different generations were identified by their bit number. The Super NES was a 16-bit console, the Nintendo 64 was a 64-bit, and so on.

So while I'm not a huge fan of 80's style video game artwork, I really love ANSI art. I used to make it for a BBS back in the 90's. I've seen some really amazing things rendered in just a few simple colors and an antique character set. And since all the characters used in ANSI drawings were expressed in only a single byte, I think that ANSI art is the forgotten 8-bit art.

I recently found an online tool that can convert your pictures into ANSI art. Below is one of my frog images rendered that way. I don't know if it will look right on all platforms (especially if you are reading this on a mobile device) but it looks ok to me in Chrome on Windows 7.




Try it with some of your own pictures!

Amphibian.com comic for 17 October 2014