Friday, May 21, 2010

Tap-A-Mole is on the Android Market!

Tap-A-Mole is a standalone version of the Whack a Mole minigame I made for our failed Adventure game attempt. It features three difficulty settings, score keeping, and the Benny Hill theme. Try it out and tell us what you think!


Thursday, May 20, 2010

For the next patch of Momenta, we look to the 90's

It's been decided that for the next patch of Momenta, we will tighten up the graphics on Level 3.



Saturday, May 15, 2010

Our centerpiece game is on Market!

We're happy and proud to release Momenta (development title Platformer) to the Market today!



As with our last Market release, you can click here if you're browsing from an Android phone, or search "Momenta" in the Android Market.



What would you pay for this Eyjafjallajökull eruption of fun? You might say $10,000, but wait, it's free! Download it, PLAY IT, enjoy it, and please provide feedback!

Friday, May 14, 2010

Our first game is on the Android Market!

Pick it up! There isn't a way to link to the market itself (unless you're viewing this on an Android phone, in which case, click here!). If you search 'Rat Race' from your phone, it's the only app that comes up.

It's free! Download it, upvote it, PLAY IT, enjoy it ^_^

Monday, May 10, 2010

Some Quick Links

Hey all,

Short update, but a few links that address a few issues that we've run into:

  • For Josh's Cup minigame (video soon!), we had some issues with Random numbers not appearing that random. This is partially to do with generating lots of random numbers consecutively (we think its generator uses the system clock as a seed, which means lots of Random numbers end up near each other if you generate them in succession). A helpful blog post details a way to get more widely distributed random numbers, albeit in O(n) time.

  • I tried answering an Android question on Stack Overflow on running out of memory in apps with lots of images. My answer was first, but I found the other answers much more instructive, themselves containing great links, and recommend it as reading to anyone wanting to optimize their graphics (which seems to be most readers of this blog, as our highest traffic consistently comes from Josh's excellent post on minimizing transparency losses.

  • Finally, while working with Preferences for Rat Race, I hit a really strange bug with ListPreference where I could get a set of options, but when I tried to select them, they would crash the application. The answer was in this excellent blog post, where you learn the dangers of letting your list labels be one type of array, but your list values be another. In Rat Race, I had to make all my numbers Strings and run Integer.parseInt(String) on all my values, but it ran!

  • New! Matt mentioned some issues with messaging, and applications that consume resources long after you've killed them. This, unfortunately, is part of the bear that comes with multitasking, and a great post describes how to responsibly exit an app, providing insights on common app-building gotchas along the way.


That last snag was the closest I've come to having stringly-typed data. ^_^

Thursday, April 29, 2010

Game updates!

The first is our new game, Platformer:



The other is an update of Rat Race, which I showed earlier:

Wednesday, April 21, 2010

SQLite gotchas

We will soon share some video of our final game, a simple platformer, but in the meantime I've run into a strange gotcha that might prove handy for others.

It's well documented that a viable way to use SQLite on Android is as follows:

  • Subclass SQLiteOpenHelper and override onCreate and onUpgrade to create your databases.

  • Call that subclass to get a SQLiteDatabase object

  • Call your SQL commands (usually queries) on the instance of SQLiteDatabase, and use a Cursor to navigate the results.


But I found a curious bug: Every time I queried my cursor, it returned 0 results. I was sure my queries were well formed, and I'd tried using both rawQuery and query. Given that I was getting 0 rows as a result, I looked at my INSERT code.

None of the many fixes I attempted did any good, and Stack Overflow was baffled with me. But the Stack Overflow snippet I posted had the culpable code, which was the method I used to retrieve the cursor:

private Cursor fetchLevelDynamics(int id)
{
  SQLiteDatabase db = this.leveldata.getReadableDatabase();
  try {
    String fetchQuery = "SELECT row_num, col_num, type_dyn FROM " + DYNAMICS_TABLE + " WHERE level_id = ?";
    String[] queryArgs = {Integer.toString(id)};
    Cursor cursor = db.rawQuery(fetchQuery, queryArgs);

    Activity activity = (Activity) this.context;
    activity.startManagingCursor(cursor);
    return cursor;
  }
  finally {
    db.close();
  }
}

Presented on its own, the error is very obvious: I close the database in the finally block, meaning the method returns a cursor pointing to a closed database.

But strangely, calling accessors on that cursor doesn't throw an exception. The Cursor instead acts as if pointing to an empty data set, going out of bounds when you call specific fields, and returning 0 on getCount.

This lame database-open/database-closed oversight was completely my fault. Still, the behavior indicated a very different problem than the actual cause, and be on the lookout if your Cursors don't return data that you suspect is present.