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!