Cocos2d-x 3.0beta2 PhysicsBody::getRotation swaps positive and negative

Hi all, I’ve discovered some strange behaviour when trying to use a sprite with its PhysicsBody property assigned, and attempting to rotate it manually. It seems that whenever you manually set the sprite’s rotation using sprite->setRotation(), the PhysicsBody update function subsequently swaps it from positive to negative and vice versa. This appears to be due to this method in CCPhysicsBody.cpp:

float PhysicsBody::getRotation() const
{
return -PhysicsHelper::cpfloat2float(cpBodyGetAngle(_info->getBody()) / M_PI * 180.0f);
}

The problem is that when using a Lerp function to smoothly rotate the sprite, it gets “stuck” between positive and negative values because this function keeps inverting them. I’ve managed to work around this by tracking the sprite’s rotation with a separate variable whose positivity does not change. If you remove the negative from the above method, the sprites no longer align properly with their respective shapes.

So, my question is, is this a bug with the framework or am I not understanding something here?

Thanks!

Can you provide sample code to reproduce this problem?

Hi, thanks for responding. It’s pretty straightforward to reproduce. Set up the PhysicsWorld using Scene::createWithPhysics() as per the documentation:

class PhysicsLayer : public cocos2d::Layer
{
...
// add following codes
void setPhyWorld(PhysicsWorld* world){m_world = world;}
private:
    PhysicsWorld* m_world;
...
}
Scene* PhysicsLayer::createScene()
{
...
// add following codes
auto scene = Scene::createWithPhysics();
scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

auto layer = HelloWorld::create();
layer->setPhyWorld(scene->getPhysicsWorld());
...
return scene;
}

Then add a sprite to the Helloworld layer and set its PhysicsBody:

sprite = Sprite::create("test.png");
auto body = PhysicsBody::createBox(sprite->getBoundingBox().size);
sprite->setPhysicsBody(body);
this->addChild(sprite);

Finally, schedule an update function (mine’s called “gameLogic”):

this->schedule(schedule_selector(HelloWorld::gameLogic), 0);

Within the update function, manually set the sprite’s rotation. Set a breakpoint on this line and you’ll see that once it’s set, on the next iteration it will swap from positive to negative. Change this to a negative and you’ll see that the opposite happens. This plays havoc with any function that may set it to a positive value on one iteration, and negative the next (such as Lerping between a positive and negative value).

sprite->setRotation(90);

It’s a bug.
I will fix it recently.
Thanks.

Ah ok, thank you very much!

This bug is fixed.
The issue link:
http://cocos2d-x.org/issues/3988
The PR link: