LDG

Analog thumb sticks for iOS using HTML5

by Matt Hackett, 2011 Aug 5
How to Make a Video Game All By Yourself

From mouse and keyboard to analog thumb sticks

You may have read before about some of the difficulties of porting Onslaught! to iOS. The first major hurdle we had to jump was getting a decent framerate. This and many other technical issues (including audio) were solved by Game Closure's SDK, but there were other critical issues to address, including a fundamental difference in user input.

Versions of Onslaught! Arena for Chrome and OSX rely on mouse and keyboard controls. Players can use the WASD keys (or arrow keys) to navigate, as well as the mouse for aiming and attacking. Obviously these input mechanisms are not compatible with touch devices. To make the jump to mobile as smooth as possible, we experimented with many different control schemes, and ended up providing players with two options:

  1. Touch to move. We labeled this as the "Beginner" option, informing players to "Use one finger." This is a streamlined, AI-assisted control scheme. Players touch the device where they want their character to move, and the character automatically attacks the nearest enemy or projectile.
  2. Analog thumb sticks. This is the (comparatively) "Advanced" scheme, asking players to "Use two thumbs." This mechanism provides players with complete control over where their character is moving, where he is facing, when to attack, and fine granular control over the angle of the thrown projectiles.

None of the decisions we made regarding user input were decided on lightly. First, we understood that analog thumb sticks have issues of their own, so we read up on best practices and studied the approach used by other popular games in the shoot 'em up genre (including Minigore and Geometry Wars). Based on this research, there seemed to be two very different approaches to the positioning of digital thumb sticks: dynamic and static.

Dynamic thumb sticks (like those used in Geometry Wars) appear on the screen only after the player touches the device, creating anchor points. Movement is then recorded as relative to those points. This has advantages such as user comfort; if one player likes to have his or her thumbs near the edge of the screen, that's fine. Likewise this method supports players who would prefer to reach farther into the device for stability or other reasons. One potential downside is that without prior visual indication, it may not be easily understood how to interact with the game or where to touch the device to begin input.

Static thumb sticks are typically always visible and in fixed positions on the screen. We decided to go with this option for a few reasons, including what we believe to be a more robust first-time experience; players new to the game could see at a glance where to put their thumbs. Additionally, it removed issues with monsters or traps being hidden beneath players' thumbs!

Technical approach

We strongly believe in code reuse so we wanted something that could easily be dropped into just about any project. This led to the creation of a Stick class that can be used like so:

var stick = new Stick(40); // 40 is the size of the input
document.addEventListener("mousemove", function (e) {
	e.preventDefault();
	stick.setInputXY(e.pageX, e.pageY);
});

This is easily rendered to the canvas element with code like:

context.beginPath();
context.arc(stick.limit.x, stick.limit.y, limitSize, 0, (Math.PI * 2), true);
context.stroke();

Examples

Below I've embedded an example that uses this class as a dynamic thumbstick that should work in most browsers. The thumb stick does not appear until input begins and controls the velocity of the green circle:



Using the same class, I've embedded another example, this time as a static thumbstick. This demo also controls the velocity of the green circle but it's been augmented with base and pivot graphics (the same graphics used in Onslaught!):

For readers who would also like to see how this is accomplished on an actual iPad, load up this page on your device.

Follow author @richtaur

LDG © 2022 • BlogTerms of ServiceVideo Policy • v2.1.2