Tag: Accelerometer

Accelerometer Player Control

If you’ve checked out the alpha release of Dead End, you will have noticed that the primary way of controlling the player is through the use of the accelerometer.

The accelerometer measures the force of gravity on the phone’s X, Y and Z axes relative to its current orientation. On earth that would mean that value can be between +/- 9.8 (although my phone maxes out at +/- 10.5, I don’t know why). Take the Z axis for instance. The Z axis runs directly perpendicular to the screen of the phone. If you have the phone standing vertical with the screen facing you, the Z axis will be completely horizontal and the accelerometer will give a 0 value for that axis. If you tilt the screen forward until it’s facing the ground then you will get the max value on that axis.

In Dead End, I take the value the accelerometer gives me and I translate this into a rotation degree for that axis. Turning the phone all the way to the left should rotate the player 90 degrees to the left. So the max value of the accelerometer corresponds to 90 degrees and the angles in between can easily be interpolated.


int mAccelMax = 10;
float mAccelMult = 90 / mAccelMax;
if(y > mAccelMax)
  y = mAccelMax;
else if (j < -mAccelMax)
  y = -mAccelMax;


rotate = y * mAccelMult;

Here, y is the accelerometer value for the y-axis. We define a value which is the accelerometer value at which the rotation should be 90 degrees. Here I made that 10, roughly the max value my phone reports. The multiplier is what interpolates the values in between. Since the max is 10 and we want to go a total of 90 degrees, each time we go up 1 on the accelerometer, we want to rotate 9 degrees. At 10, this will be 90 degrees.

If you want to make the tilt control more sensitive then all you have to do is lower the max value. This will cause mAccelMult to increase which increases the rotation each time we go up 1 on the accelerometer.

You can also redefine the center of rotation, the point where the accelerometer reports 0 and rotation is 0. This allows players to decide how the orientation that they hold the phone at rather than defining it for them. To do this, just subtract the accelerometer value of the point you want to be the center from the current reading.


y -= mHorizontalCenter;


int mAccelMax = 10;
float mAccelMult = 90 / mAccelMax;
if(y > mAccelMax)
  y = mAccelMax;
else if (j < -mAccelMax)
  y = -mAccelMax;


rotate = y * mAccelMult;

As you can see, this is the same code as before except for the very first line.

It's easy enough to use the options menu to allow the player to set tilt sensitivity and horizontal/vertical centers.

Next time I'll post about a problem I had with tilting the phone too much in one direction while having a custom centering point.


Accelerometer Smoothing

Some of the feedback for Dead End was mentioning that the tilt controls were too jerky. I’ve noticed this before and tried to fix it before but never did. It was especially noticeable when using the tilt aiming in a moving vehicle or while a little kid is jumping on the couch next to you.

Last time I tried to fix this, I googled for “Accelerometer Smoothing” and picked one way of handling it. The fix was way too complicated and didn’t work. Coming back to the problem, I did the same thing again and this time found a much, much simpler approach. I have no idea how I didn’t find this solution before but I’m glad I did because now the tilt movement is way smoother.

The solution is called a low-pass filter. It essentially filters out any drastic changes to the accelerometer values so that objects controlled by the accelerometer move at a more gradual pace.

float accelFilter = 0.25f;
x = x * accelFilter + lastX * (1 - accelFilter);
...
Do something with accelerometer values
...
lastX = x;

That’s really all there was to it. Incredibly simple and yet for some reason it took me this long to find it.


Copyright © 1996-2010 Infectious Entertainment. All rights reserved.
Jarrah theme by Templates Next | Powered by WordPress