Monday, January 19, 2009

Announcing Sandblaster 1.7!

As promised yesterday, I've wrapped up the next set of new features for Sandblaster and am ready to release them to the Android Market. Changes in this release include:

  • New drawing tools and tool settings.
  • More speed improvements.
  • Faster switching between portrait and landscape orientations.
  • Status notifications to let you know your file was saved.



You'll now find a few new items at the top of the screen. This is the new toolbar, which was the main focus of this release. This toolbar includes a tool selector on the left, a pen size slider in the middle, and a preview of what the drawing mode looks like on the right. Here's a quick rundown of the new tools:

Spray tool



The spray tool is the default pen style. This draws not-quite-solid circles of the selected element wherever you touch or drag your finger on the screen.

Pen tool



The pen tool is like the spray tool, except that it draws solidly.

Spout tool



The spout tool allows you to continuously stream elements onto the screen. This replaces the old feature of holding your finger in place on the screen for half a second (which was pretty much impossible on actual phones).

Line tool



The line tool helps you draw perfectly straight lines of any element.

Hogging focus in Android

If you're implementing a game that uses the trackball, you probably don't want the default behavior of using the trackball to navigate between focusable elements. In my case, I use the trackball for moving around the screen (especially useful when zoomed in). As I added buttons on the screen, they began stealing focus, making it impossible to use this feature.

I tried a few things to resolve this problem, and it took a while to find what seems to be the best solution. First, I tried setting android:focusable="false" on pretty much everything in my layout XML files. This seemed to have no effect whatsoever, and left me with no other clear options.

There were a few other hacks I tried. I tried manually calling view.setFocusable(false); on the top-level controls, and although ugly and tedious, this almost worked. The only problem was with the ZoomControls widget, which is a compound widget comprising two buttons. These child buttons would end up getting highlighted as if focused, but never really kept focus. The trackball panning feature worked, but one of the buttons would end up permanently highlighted.

I eventually decided to look for a way to walk all the views in a tree, to make them all unfocusable as an act of desperation. Fortunately, I encountered the setDescendantFocusability method in the ViewGroup class. I tried setting this to FOCUS_BLOCK_DESCENDANTS on my top-level view, and this did a great job of preventing any controls from highlighting, but also blocked all the trackball events. I tried requesting focus explicitly for the top-level view, but this had no effect. Finally, I explicitly set the view to be focusable, and that fixed the feature!

In short:

public SandView(Context context, AttributeSet attrs) {
super(context, attrs);
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
setFocusable(true);
requestFocus();
}

Sunday, January 18, 2009

The evolution of Sandblaster: The next two weeks

In my previous post, I showed how Sandblaster developed in its first three days. After those first few days, I had to return to work, and development became sporadic. I also started working on more useful and difficult features. This post shows how Sandblaster has developed since that time, as well as a couple new features that are yet to be released.

Sandblaster 1.5






January 3, 2009. I spent the last couple days of my New Year holiday implementing some major features for this next release. I knew that soon I'd be heading back to work, and I was afraid I wouldn't have the time or energy to work on anything significant, so I wanted to make sure I put out a really strong release before it was too late.

The main feature I worked on was saving and loading of "snapshots." This allowed the same drawings to be preserved across different invocations of the application, as well as across zoom levels and orientation changes. I tried to make this feature a little fancy by generating and displaying thumbnails of each snapshot when browsing them. This feature was a lot of work, because I had to learn how to use more of Android's UI toolkit.

I also changed how zooming in or out worked. In previous releases, changing the zoom level actually cleared and generated a new level. In this release, all levels became the same resolution, but the zoom level allowed you to make the particles larger or smaller. By default, the scale would be appropriate to fit the entire level on the screen, and I picked a level resolution that would allow a reasonable frame rate for most drawings.

This release had a few other little finishing touches, like icons for menu items, panning with the trackball, etc.

Sandblaster 1.6





January 12, 2009. Right now this is the latest version I've released. This was the first release since returning to work, and came nine days later than the previous one. Fortunately I was still finding time and energy on weekends to get some significant work done.

I spent a lot of time during this release cleaning up and reorganizing my code. This had become necessary just to be able to proceed with some of the features I wanted to add. Despite the distraction of work and the overhead of refactoring, I somehow found time to work on several major features, too.

The first feature I implemented was a simple play/pause button. I then decided an undo button would go along quite nicely. This, however, required implementing a faster method of saving and loading more complete snapshots, so I basically rewrote all that code to use Java data streams instead of XML. The undo feature worked by having a new snapshot pushed onto a stack every time the user performed an undoable action (drawing or pressing the play/pause button). Pressing the undo button would pop the latest snapshot and recreate the sandbox in its previous state.

After implementing playback control and undo, I looked into optimizing performance again. I made physics a little faster, and rendering a lot faster. While I was at it, I also changed how density worked and added viscosity. In previous releases, elements always sank or floated through other elements as quickly as possible. I changed it so that the rate depended more on how different the two elements' densities were. This made things appear more buoyant, natural, and interesting. The addition of viscosity allowed some variation in how steeply things pile up (or how rapidly they flatten out).



Finally, to wrap up this release, I added an eraser, a larger (but still fixed) pen size for drawing thicker lines, and a new demo. For the demo, I harnessed my ASCII art skills to create an hourglass. However, I was afraid people might think it was just the game's loading screen, so I added some dynamic branding.

The Future





I'm getting very close to releasing the next version of Sandblaster, which will be 1.7. I've been experimenting with a few changes that haven't really panned out, but now I'm concentrating on providing better drawing options. I'd like to make it so you can select between "pen", "spray", "spout", and "line" modes, and change the size of the pen with a slider. You can see a rough draft to the left. Once I fix a bunch of bugs, create some icons, and polish the interface, this will be ready for release!

The evolution of Sandblaster: The first three days

I started developing Sandblaster on December 30, and followed a release-early-and-often policy from the beginning. I was able to slap together a package and deploy it on the Android Market on the first day (along with two more releases on the same day!). I suppose I was excited at the time, but, looking back only three weeks later, these releases look pretty embarrassing.

This post documents my progress during those first three days of frantic but primitive work. In my next post I'll show what happened as I started spending more and more time between releases.

Sandblaster 1.0



December 30, 2008. Such a primitive game! During this first release, I was more interested in the particulars of how Android applications are packaged and deployed on the Market, so there were no real features or polish. It also didn't help that I didn't know enough about the Android framework to know how to add the features I wanted or make anything look good.

This was also my first attempt at a falling sand game. I really hadn't thought through the physics at all, and I hadn't actually played one in a while. This release did everything very inefficiently, and only barely suggests at its purpose, but one has to start somewhere.

Sandblaster 1.1



December 30, 2008. Shortly on the heels of my very first release came this first upgrade. I noticed it was impossible to tell what this application was for, so I created a crude demo that loaded up whenever you started the application (or changed the screen size).

Another glaring change is that I switched from rectangles to circles for drawing the particles. I think this rendering choice was pretty unpopular. I can understand why, as it's rather jarring to see each particle teleporting from one position to the next, since there's no animation between iterations.

Sandblaster 1.2.1



December 30, 2008. This release had an extra .1 tacked onto the end of it because I shipped a 1.2 release that crashed if your finger got too close to the lower right corner of the screen. This was the third release on that first day of development.

In my first two releases, drawing walls had been really annoying, because I did not draw connecting lines between the points where I detect your finger dragging across the screen. In this release I added those lines, so shapes could be drawn much more naturally (like bowls to catch water). This release was also somewhat faster than the previous ones.

Sandblaster 1.3



December 31, 2008. Before getting started with my New Year's Eve partying, I spent the day trying to make my game much more enjoyable. I started making use of the Android SDK's profiling tools to begin optimizing my physics and rendering loops. This became a task for me to do in every release cycle since. By optimizing the program, I was able to push the resolution higher without slowing down the frame rate. This makes the game look much more like a falling sand game!

In addition to making the game faster, I switched back to drawing with rectangles. I felt like I had some computation time to spare, so I added some more features to the physics engine. The biggest physics enhancement of this release is that particles settled from piles into flat pools for the first time (which makes the water a bit less fake, provided the frame rate stays high enough). I also rearranged the drawing elements to be more like my favorite falling sand games, adding salt and oil and their related effects.

Sandblaster 1.4



January 1, 2009. This was the first release of 2009, and since it was following a New Year's hangover, it was much less ambitious than the previous day's work. This release was about adding some user documentation to the application, so I created labels for the drawing elements at the bottom of the screen, and a help page to describe it all.

The Future


After those first three days, I began putting more work in between each release. It feels like I crossed a threshold where my standards went higher, as well as the amount of work required to meet those standards. In my next blog post, I'll show how those higher standards applied, and what to expect from the next release I put out.

Wednesday, January 14, 2009

Welcome to the Sandblaster Development Blog

Hello! I'm Logan, and I've made a simple toy for Android phones called Sandblaster. It's a falling sand game heavily inspired by the games you find at http://fallingsandgame.com/sand.

I've been working on this game off and on for two weeks now (having started it in earnest on December 30, 2008), and it's come a long way already. In the process I've learned an awful lot about development on the Android platform, the pseudophysics behind falling sand games, optimizing Java, healthily absorbing user feedback, and more. I've made the game open source from the beginning, so everyone can see a lot of the bad code I write (and hopefully some good code too), and perhaps help me make it better.

I've decided to start this blog because I don't want to forget what I've learned in the process. I also think it could become a forum for people who like the game to learn how it works, anticipate upcoming features, and provide me with good feedback. Expect several posts soon about Android, optimization, game ideas, and more!