JBox2D Testbed Update + Serialization

So I’ve noticed two major issues people have with jbox2d:

  1. Getting the engine running
  2. Debugging strange behavior

The first issue usually comes from trouble with surrounding application, where graphics isn’t quite right or the engine isn’t getting initialized/updated correctly.  The second issue comes both from with the slightly steep learning curve of the Box2D API, and the finicky nature of physics engines in general.  A good way to solve both of these is a simple platform which provides all of the application and graphics layers so you can test and experiment with just physics code.

The jbox2d testbed is meant to solve this problem, but it hasn’t been too developer-friendly in the past.   So I’ve just given it an upgrade!

The current features now include:

  • controllable run loop
  • easy input support
  • serialization (saving/loading)
  • expandable ui settings
  • simple automatic drawing with j2d
  • all in a multi-platform java swing application

Check out the wiki page for implementation info, and check out the current tests here for example.  Also, keep in mind the testbed is not intended for commercial use, and it might be subject to changes in the future.

Next, you may have notices the “Save” and “Load” buttons in the testbed.  This is because I’ve added world serialization!  Currently the supported format is Protocol Buffers (quick and tiny serialization), and the framework is extendable for more formats.  Hooray!

Google Analytics tracking with Java

After you start using Google Analytics, it’s pretty hard to stop. The ability to see stats and trends from users is invaluable to successfully maintaining software. Working with Adobe Flex, it was easy to set up google analytics tracking, as libraries were provided. But I was surprised to find that there was no library provided for sending tracking data in Java. The data export api is there, but nothing to send the tracking data. After doing some quick research, I decided to make my own.

The documentation provided by google here was pretty helpful, but not quite from complete (and not completely correct, I think it’s a bit outdated).  So anyways, I present JGoogleAnalyticsTracker!

JGoogleAnalytics tracker is lightweight (19kb, 6 classes) library designed to be simple an unobtrusive. Using the tracker is dead simple. You start my making your configuration data, which represents the machine making the request. This has stuff like the tracking code, java version, screen resolution, etc. Most of the stuff is populated automatically, the only thing it can’t figure out is the flash version.

AnalyticsConfigData config = new AnalyticsConfigData("MyTrackingCode");
// if you want to set your own config parameters:
config.setFlashVesion("9.0 r24");
// etc

Next, just create the tracker with your configuration and you’re good to go:

JGoogleAnalyticsTracker tracker = new JGoogleAnalyticsTracker(config, GoogleAnalyticsVersion.V_4_7_2);

And that’s it. You can track page visits, referrals, searches, events, and even make your own custom request and fill out whatever data you want for the tracking parameters. The tracker can out these requests in three different modes, synchronous, asynchronous, and queued (default). See the project page for more info.

For complete documentation, see the javadocs, or just view the source, it’s very straightforward.

Java URI encoder

Recently I discovered that the URL encoder provided in Java is meant for forms and headers, and not actual URLs.   After looking at the URI spec here, I created a quick and compact URI encoder for java:

/**
 * simple uri encoder, made from the spec at http://www.ietf.org/rfc/rfc2396.txt
 * Feel free to copy this. I take no responsibility for anything, ever.
 * Thanks to Marco and Thomas
 * @author Daniel Murphy
 */
public class URIEncoder {
  private static final String mark = "-_.!~*'()\"";
  private static final char[] hex = "0123456789ABCDEF".toCharArray();

  public static String encodeURI(String argString) {
    StringBuilder uri = new StringBuilder();

    char[] chars = argString.toCharArray();
    for (int i = 0; i < chars.length; i++) {
      char c = chars[i];
      if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
          (c >= 'A' && c <= 'Z') || mark.indexOf(c) != -1) {
        uri.append(c);
      } else {
        appendEscaped(uri, c);
      }
    }
    return uri.toString();
  }

  private static void appendEscaped(StringBuilder uri, char c) {
    if (c <= (char) 0xF) {
      uri.append("%");
      uri.append('0');
      uri.append(hex[ c]);
    } else if (c <= (char) 0xFF) {
      uri.append("%");
      uri.append(hex[ c >> 4]);
      uri.append(hex[ c & 0xF]);
    } else {
      // unicode
      uri.append('\\');
      uri.append('u');
      uri.append(hex[ c >> 12]);
      uri.append(hex[(c >> 8) & 0xFFF]);
      uri.append(hex[(c >> 4) & 0xFF]);
      uri.append(hex[ c & 0xF]);
    }
  }
}

Edit: Updated with char-to-hex speed improvements, fixed < 15 bug, and now encodes unicode chars if > 0xFF