Developing Android Applications with Adobe AIR [43]
A Simple Animation
Let’s create a simple animation along the x- and y-axes. A multiplier is used to boost the values so that our ball object moves around the screen at a reasonable rate:
import flash.display.Shape;
const MULTIPLIER:Number = 8.0;
var accelerometer:Accelerometer;
var ball:Shape;
ball = new Shape();
ball.graphics.beginFill(0xFF9900);
ball.graphics.drawCircle(0,0, 50);
ball.graphics.endFill();
ball.x = stage.stageWidth/2;
ball.y = stage.stageHeight/2;
ball.cacheAsBitmap = true;
addChild(ball);
accelerometer = new Accelerometer();
accelerometer.addEventListener(AccelerometerEvent.UPDATE, onUpdate);
function onUpdate(event:AccelerometerEvent):void {
ball.x -= event.accelerationX * MULTIPLIER;
ball.y += event.accelerationY * MULTIPLIER;
}
Move your device and see how the ball follows your movement. As before, if you move in a more abrupt fashion, the ball will also move faster.
This is a good first try, but there is a lot we can do to improve responsiveness and animation.
Updates and Screen Rendering
The device defines the frequency of sensor updates. You cannot obtain this information through the Android or AIR API. You can, however, overwrite it to conserve battery life. The value is in milliseconds:
accelerometer.setRequestedUpdateInterval(30);
Do not use every AccelerometerEvent update to redraw the screen. This drains the battery and moves too fast for the frame rate at which the screen is redrawn. Instead, store the value on update and redraw the screen on the ENTER_FRAME event. You will notice a much smoother animation and better overall performance:
import flash.events.Event;
import flash.events.AccelerometerEvent;
import flash.sensors.Accelerometer;
const MULTIPLIER:Number = 20.0;
var vx:Number = 0.0;
var vy:Number = 0.0;
var accelerometer:Accelerometer;
accelerometer = new Accelerometer();
accelerometer.addEventListener(AccelerometerEvent.UPDATE, onUpdate);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
function onUpdate(event:AccelerometerEvent):void {
vx = event.accelerationX * MULTIPLIER;
vy = event.accelerationY * MULTIPLIER;
}
function onEnterFrame(event:Event):void {
event.stopPropagation();
ball.x -= vx;
ball.y += vy;
}
Notice the event.stopPropagation method called in the onUpdate function. It is important to eliminate unnecessary steps, especially if you have a deep displayList.
NOTE
The event flow sends an event throughout the display list, from the top, looking for event listeners that may have been defined along the way and then bubbled back up. StopPropagation() stops the process as soon as the event finds the target.
Setting Boundaries
Keep your animation within the boundaries of your screen. Set the values of the boundaries, and only move the ball if the position change is within them:
var radius:int;
var xBounds:int;
var yBounds:int;
var newX:Number = 0.0;
var newY:Number = 0.0;
radius = ball.width;
xBounds = stage.stageWidth - radius;
yBounds = stage.stageHeight - radius;
function onEnterFrame(event:Event):void {
event.stopPropagation();
newX = ball.x - vx;
newY = ball.y + vy;
if (newX > radius && newX < xBounds) {
ball.x = newX;
}
if (newY > radius && newY < yBounds) {
ball.y = newY;
}
}
In this example, the boundaries are defined by xBounds and yBounds. They represent the dimension of the stage minus the radius of the ball being animated.
Rotating Toward the Center
In this example, the ball turns toward the center of the screen while it is moving. Making an element react to its environment brings it to life.
With the following code, the larger ball now contains a small ball that is off-centered so that the rotation is visible:
import flash.events.Event;
var ball:Shape;
var centerX:int = stage.stageWidth/2;
var centerY:int = stage.stageHeight/2;
var newX:Number = 0.0;
var newY:Number = 0.0;
ball = new Shape();
ball.graphics.beginFill(0xFF3300);
ball.graphics.drawCircle(0,0,