# Accelerometer based games smoothness

Take Doodle Jump and other games that rely on the accelerometer. The movement of the character is very smooth and I have no idea how they implemented it. I've seen a number of SO/GameDev/forum questions, but the discussion ends abruptly when someone recommends a high/low pass filter. I've tried that (unless I'm missing something) and the results are nowhere near smooth.

All I'm trying to do is move a character on the x axis. This is the code I have and it's very "choppy". It's actually the code you can see on the official Android tutorials.

float alpha = 0.9f; //tried many values from 0.1f to 0.99f. chopiness still there

@Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if(init) {
gravity[0] = event.values[0];
gravity[1] = event.values[1];
gravity[2] = event.values[2];

init = false;
} else {
gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
}

// Remove the gravity contribution with the high-pass filter.
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];

character.setX(character.getX() - linear_acceleration[0]);

}


I also tried multiplying linear_acceleration[0] with a sensitivity, where 0 < sensitivity < 1 but the choppiness still doesn't go away. What is the next step from here to achieve a smooth movement like in Doodle Jump?

• It's not "high/low pass filters" that remove choppiness. It's low pass filters specifically. What you have is a high pass filter, which does not remove choppiness. – congusbongus Apr 8 '14 at 0:34
• @congusbongus I'm implementing this now: stackoverflow.com/a/5780505/1991295 Still absolutely no difference. – async Apr 8 '14 at 17:04

OK, I managed to sort this out and it was a bit stupid. Yes, the low-pass filter DOES solve the problem. Actually here's my code (note I'm doing it in a different method, but just copy and paste the contents in onSensorChanged(SensorEvent) if you wish:

private static final float alpha = 0.65f;
private static final float SENSITIVITY = 1f/128;
private boolean firstTime = true;

@Override
public void handleSensorEvent(SensorEvent event) {
if(firstTime) {
vals[0] = event.values[0];
vals[1] = event.values[1];
vals[2] = event.values[2];
}

vals[0] = vals[0] + alpha * (event.values[0] - vals[0]);
vals[1] = vals[1] + alpha * (event.values[1] - vals[1]);
vals[2] = vals[2] + alpha * (event.values[2] - vals[2]);

character.setX( character.getX() - vals[0] * SENSITIVITY );
}


You can calibrate alpha and SENSITIVITY according to your needs. Now this is why this code was producing very choppy movement initially: in my activity's onResume() I was registering my listener using SensorEvent.SENSOR_DELAY_NORMAL. That is wrong. What you have to do is register it with SensorEvent.SENSOR_DELAY_GAME. I think the reason behind this is obvious. So in your activity's onResume():

sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);


where accelerometer is declared as (in onCreate()):

accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);