Thursday, September 10, 2009

Why Android Flies

The main mode of movement in Replica Island is flying. The Android robot has thrusters in his feet, and while he can also slide upon the ground, most of the game is spent maneuvering through the air. Enemies are dispatched by dropping on them from above and the collision and physics systems make it easy to glide off of a ramp and into the air. I don't think this is a common approach for side scrolling platformers.

The reason that the Android flies is that many Android devices ship with a trackball. Some (like the Samsung Galaxy) have a d-pad, which works fine as well, but the devices from HTC (which include the G1, myTouch, and Hero) all sport a trackball. The great thing about a trackball is that it's an analog interface with a pretty high resolution. The bad thing about it is that you can't hold a single direction down like you can with a d-pad; to keep sending input events in a specific direction, you have to keep rolling in that direction.

When I started working on Replica Island, I knew that I'd have to do something different with the player controls to afford trackball use. Letting the Android robot fly seemed like a good solution: the player gets going in a certain direction and then only has to make minor adjustments in heading to steer rather than constantly depressing a button indicating the direction that they wish to travel. This sort control scheme is a bit like a car steering wheel--given velocity that you already have you just need to worry about turning left and right. Indeed, in early prototypes it was clear that the trackball would work very well for this sort of analog maneuvering, but I also quickly learned that it's hard to make precise movements with a trackball.

My initial implementation let the player move left, right, and up by rolling the ball, and while it worked and was playable, people had a really hard time moving in only one direction. It was too easy to accidentally roll up a little when trying to go left or right, which made the controls feel unwieldy and arbitrary. After experimenting with dead zones and other input filters, I finally reduced the trackball to horizontal movement and put a jump/fly button at the lower-left hand corner of the screen. This is a much better solution because it allows players to manage their horizontal and vertical velocity independently, much like they can with a d-pad or other traditional game input device. Furthermore, by ignoring vertical movement on the trackball the control scheme became a lot more forgiving to minor input mistakes.

Replica Island is playable with three inputs: the jump/fly button, left and right controls, and a drop/attack button. These three inputs were decided upon to allow the trackball to feel good, but they map well to other input systems (like a hardware keyboard or d-pad) too, so Replica Island is playable on a wide range of hardware.

Once I settled on the trackball-based steering approach for movement, many other aspects of the core game design fell out. I posted earlier about the collision detection system I wrote to support slopes and angles; this system was necessary to allow for ramp and bounce physics. The Android robot can slide across the ground but it's a lot more fun when he's in the air, so I needed to have a collision and physics system that allows him to take flight easily. Sliding down hills or going off ramps feels good and works well with the control scheme.

This approach also simplified animation: if the Android robot is going to fly with thrusters in his feet, he doesn't need a walk cycle, a run cycle, a turn animation, a skid to stop animation, a jump windup or a jump peak or a jump fall animation. His motion system is more complicated than most of the side scrollers I've made in the past but his animation system is extremely simple; the control scheme afforded this simplicity.

As awesome as Android is for games, the devices it runs on are not generally designed explicitly for gaming. To make a fun game, especially one that is part of an established console-oriented genre, you need to come up with a control scheme that works well for the hardware, even if there's not a lot of precedent for it. In the case of Replica Island, I started with the control scheme and the rest of the game design flowed out from there; as a result, I think that it's a quite playable platformer despite its rather unconventional controls.

When making games for this type of system, it's important to consider exactly how the available inputs are going to make the game fun; if you try to just glue controls from some other hardware paradigm onto a game running on a phone the results are almost guaranteed to suck. Getting the controls right is probably the single most important task you have as a game developer, and if you can nail them down early enough, a huge part of your game design will pretty much write itself.


  1. How are you reading the trackball events? I am only able to get touch events from GLSurfaceView

  2. GLSurfaceView implements SurfaceHolder, which isn't the right spot to intercept events. The parent Activity of the surface is where the onTrackballEvent() callback can be overridden.

  3. Having played the game for a bit, you made absolutely the right choice control-wise.

  4. Hi Chris, we are a pair of developers who are working on a fast pace 2d scroller using your awesome Replica Island as a base code. Our character needs to be in ATTACK state while jumping, currently we succesfully identify the start of a jump, however the end of it is a bit tricky. When the player fall down and don't move nor is pressing the jump button the mtouchingGround method or variable is FALSE, however if the player is pressing the jump button or applying horizontal impulse, the same variable/method returns TRUE then we can know when a jump finishes. I would appreciate any help, tips or suggestion about it. Thanks.

  5. Man do I miss this game on my Hero! Thanks for many hours of fun... tried it on my Evo but without the trackball it just wasn't there. Definitely was the best game taking advantage of that short-lived control option!!!