Accelerometer Event
The accelerometer is fun!
First, we have to activate the accelerometer in the init() method.
Device::setAccelerometerEnabled(true);
As usual, we need to create an event listener but this time for the accelerometer. Although, unlike the previous listeners, this one needs a callback function as an input parameter. Then we add the listener to the event dispatcher.
// EventListenerAcceleration::create(const std::function<void (Acceleration *, Event *)> &callback) auto listener = EventListenerAcceleration::create(callback); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
I define a lambda for the callback function in the format below and I pass the local variables that I need in the brackets:
function<void(Acceleration*, Event*)> callback = [](Acceleration *acceleration, Event *event){
// do something
}
Just keep in mind that the accelerometer drains your phone’s battert. So, use it wisely!
Accelerometer Example
In this example I make a ball sprite and move it around with the accelerometer.
I am just listing the init() method here as the rest are the same business as before which by now you know by heart!
AccelScene.cpp
bool AccelScene::init()
{
// Setup the ball sprite
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
float x = origin.x + visibleSize.width / 2;
float y = origin.y + visibleSize.height / 2;
auto ball = Sprite::create("ball.png");
ball->setVisible(true);
ball->setPosition(x, y);
this->addChild(ball);
// Setup the accelerometer event handler
Device::setAccelerometerEnabled(true);
// The callback lambda
function<void(Acceleration*, Event*)> callback = [ball, visibleSize, origin](Acceleration *acceleration, Event *event){
// Update the ball position using the accelerometr x and y values
float x = ball->getPositionX();
float y = ball->getPositionY();
x += (acceleration->x * 10);
y += (acceleration->y * 10);
// Make sure the ball stays in the screen
if (x < origin.x) x = origin.x;
if (y < origin.y) y = origin.y;
if (x >= (origin.x + visibleSize.width)) x = origin.x + visibleSize.width - 1;
if (y >= (origin.y + visibleSize.height)) y = origin.y + visibleSize.height - 1;
// Update the ball position
ball->setPosition(x, y);
cout << acceleration->timestamp << " " << acceleration->x << " " << acceleration->y << " " << acceleration->z << endl;
};
auto listener = EventListenerAcceleration::create(callback); // Create an accelerometer listener
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
return true;
}
After running this code, I realized the starting position of the phone (the angle you hold it) registers as the initial pose somehow! You can enhance this code to compensate for that, but I leave that to you!