Unable to get accelerometer values in version 3.0

Hello,
I’m trying to get the accelerometer to work by using the Event Dispatcher because Layer::setAccelerometerEnabled is deprecated in version 3.0. However, I never get the callback for accelerometer events.

Here’s my code:

bool HelloWorld::init()
{
    // super init
    if ( !Layer::init() )
    {
        return false;
    }

    // add accelerometer listener
    auto accListener = EventListenerAcceleration::create(CC_CALLBACK_2(HelloWorld::accelerated, this));
    Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(accListener, this);

    return true;
}

void HelloWorld::accelerated(cocos2d::Acceleration *acceleration, cocos2d::Event *event) {
    // never gets here...
}

What did I do wrong?

I have the same problem, setAccelerometerEnabled(true) does not have any effects

void onAcceleration(cocos2d::Acceleration *pAccelerationValue) is not called on the layer at any time

I can confirm that the Acceleration event does not fire in 3.2rc0.

I have the following setup code called within a layer’s init() method:

void RjsLayer::onEnter() {
        Layer::onEnter();

Device::setAccelerometerEnabled(true);
        EventListenerAcceleration* listenerAcceleration = EventListenerAcceleration::create(CC_CALLBACK_2(RjsLayer::onAcceleration, this));
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenerAcceleration, this);

EventListenerTouchOneByOne* listenerTouch = EventListenerTouchOneByOne::create();
        listenerTouch->onTouchBegan = CC_CALLBACK_2(RjsLayer::onTouchBegan, this);
        listenerTouch->onTouchMoved = CC_CALLBACK_2(RjsLayer::onTouchMoved, this);
        listenerTouch->onTouchEnded = CC_CALLBACK_2(RjsLayer::onTouchEnded, this);
        Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listenerTouch, this);
    }

(the editor in this website is rubbish so I haven’t used the code block, sorry)

The touch events work but the acceleration event does not. Stepping through the code the device event fires but that does not reach the event delegate.

This is a bug. I created the ticket: http://cocos2d-x.org/issues/5708

Thanks for creating a ticket for this, I’ll also mention it to the engineers.

for code blocks, use MarkDown. Start a block with 3 ticks (above your tilde) and “cpp” and and with 3 ticks.
Like:

```cpp
your code
```
std::string s = "Test";

seriously?
It seems to me that it is getting harder, not easier, both to figure out cocos2d and get info about it.

It’s potentially a great platform, but hampered by
Poor documentation
Awkward to use site
lack of concise documentation

I am, getting more and more disillusioned about cocos.

It isn’t all about the ‘next fantastic feature’ - if you continue the way its going you will put off more and more new users -

how in the name of the green beast of thaaaal is anyone supposed to just know that to do a code block in the forums you need to do three single-quotes?

If it goes on like this I predict the death of Cocos2d-x you have GOT TO make it easy to use, and so easy to get help!

@Maxx

I’m sorry that you are, obviously, frustrated with Cocos2d-x

We do know the documentation needs attention and we have things underway to fix this.

how in the name of the green beast of thaaaal is anyone supposed to just know that to do a code block in the forums you need to do three single-quotes?

I’m not sure why you sound a bit bent out of shape about this? These forums and most forums out there are based upon Markdown. Markdown makes it very simple once you know some syntax. The user above mentioned (the editor in this website is rubbish so I haven't used the code block, sorry) so I simply told him how to create a code clock.

About the death of cocos, I think you might just still be frustrated. Cocos2d is not one of those game engines that it totally GUI driven for development. We aren’t Unity or UnReal. We do things different. A Cocos2d-x user definitely needs to enjoy programming and be able to program to succeed in creating their game. We do have tools that are trying to ease the pain but again these take time.

If you really are out in left field, PM me and lets chat about what you need clarification on and I’ll help.

Hi,
Firstly, sorry for the rant.
It was the end of a long day, most of which I had spent trying to implement the accelerometer code into PooperPig.
In the Cocos2d-iphone version it probably took me a couple of hours to have something working.
When i moved to Cocos2d-x I took the opportunity to rewrite from scratch - so everything i implement i try to see bow it should now be done best. At best thats a moving target.
when I added the code i found, and just cclogged the angle of the device, it almost seemed as if the changes were being delayed so i’d turn the device and several seconds later the values would change…
i eventually tried changing the accelerometer interval and that seemed to improve things.

I still dont understand why this makes a difference, and what differs from the cocos tests

Still, i persevere,

On the formatting in the forums front, i agree that different forums use different markup, but those programming forums that I use all have a simple button to format code - my brain is much too full at my advanced years for me to give over any neurons to remembering different syntax for different sites!

Excuse the typos - i am writing this on a Windows 8 tablet, which would serve better as a place mat, frankly!

even in 3.2 callback function is not getting called.
can anyone help?

Since more users are having this frustration I asked our dev team to take a look at the bug report that was mentioned above.

There is a test case in NewEventDispatcherTest.cpp for accelerometer. And it works as expected.
Have your enabled accelerometer

Device::setAccelerometerEnabled(true);

And i use cpp-empty-test to test it. It can work with Layer too.
What i did is:

  1. add virtual void onAcceleration(cocos2d::Acceleration* acc, cocos2d::Event* unused_event); in HelloWorldScene.h

  2. invoke setAccelerometerEnabled(true); in HelloWorld::init()

  3. implement onAcceleration like this

void HelloWorld::onAcceleration(cocos2d::Acceleration *acc, cocos2d::Event *unused_event)
{
    log("accelerometer");
}

@zhangxm thanks for the reply.
I got my code working by calling this->setAccelerometerEnabled(true);
instead of Device::setAccelerometerEnabled(true);
:smile:

Device::setAccelerometerEnabled(true); just calls the native functions, but does not set the listener, if you have never set them. If they wer set in the first place, you can just call Device::setAccelerometerEnabled(true);

The following code would remove the listeners, even when the accelerometer was never added before.
Shouldn’t the code test, if there is something to be removed in the first place, so that the code is consistent and not wasting unnecessary cycles?

On the other side, the code is not called many times throughout a game.

/// isAccelerometerEnabled setter
void Layer::setAccelerometerEnabled(bool enabled)
{
    if (enabled != _accelerometerEnabled)
    {
        _accelerometerEnabled = enabled;

        Device::setAccelerometerEnabled(enabled);

        _eventDispatcher->removeEventListener(_accelerationListener);
        _accelerationListener = nullptr;

        if (enabled)
        {
            _accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(Layer::onAcceleration, this));
            _eventDispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);
        }
    }
}

@iQD I use a similar method to this. But find, I get random delays in acceleration…

I feel the acceleration was much easier/responsive under cocos2d-x v2.2.2 (my last version), and cocos2d.

I even output acc->x or acc->y to see the values, just seems very unresponsive at the best of times. Especially when you want to control the movement of an object. I can tilt the device to it’s maximum… it still takes ages to register. Especially when applying it to a Box2d body applyLinearImpulse for instance.

Some thing just doesn’t feel right.

Now all events(include accelerometer event) are dispatched by EventDispatcher. So it may have delay. We will try to find how to fix it.

I have have success getting the accelerometer data with this code called from the in the scene:

_accelerometerEnabled = true;
Device::setAccelerometerEnabled( true );
_accelerationListener = EventListenerAcceleration::create(CC_CALLBACK_2(GSFRPlayScene::onAcceleration, this));
_eventDispatcher->addEventListenerWithSceneGraphPriority(_accelerationListener, this);

which calls method:

void GSFRPlayScene::onAcceleration(Acceleration* acc, Event* unused_event)
{
  _lastAcceleration.x = acc->x;
  _lastAcceleration.y = acc->y;
  _lastAcceleration.z = acc->z;
}

But frequently the output is super slow to respond, seems like its almost 2-3 second delayed, and sometimes requires a restart of the app to get the data consistently flowing. It’s so inconsistent that I have to consider taking out this functionality which was a selling point to our client.

What device did you test on?
And how to reproduce it?

Well i have galaxy s4 running 4.4.2 and using cocos2dx-3.2 and No delay at all

@smitpatel88
Thanks for sharing.

@hawkwood
Will you checkout it in Cocos2dxAccelerometer.java.
Cocos2dxAccelerometer.onSensorChanged() will receive accelerometer event from system.
If it is slow, then may be you can invoke Cocos2dxAccelerometer.setInterval() to have a try.