I am using Box2D to simulate the physics world independently of my sprites, and I update the position of my sprites based on the position of b2body.
I have a player that consists of two fixtures. One fixture is not a sensor and can make contact with the ground. The other fixture is a sensor and is used to check for contacts with things like powerups eatables etc.
. I have some bodies (eatables, powers) in which the fixture consists of a single sensor that can make contact with the player sensor.
In iOS everything works fine - when the player collides with the powerup / eatable, he continues running as if nothing is wrong. But in Android he bounces off the powerup.
What could be the problem ? The plist file generated by physics editor is the same for both. Why should the simulation be different ? Box2d is part of cocos2d, so the library is the same and should be the same for both.
I am using cocos2d-x 3.7.
EDIT: I use the following:
ContactListener.h class:
class ContactListener : public b2ContactListener {
public:
void BeginContact(b2Contact* contact) {
void* bodyUserDataA = contact->GetFixtureA()->GetBody()->GetUserData();
if (bodyUserDataA) {
}
}
void EndContact(b2Contact* contact) {
}
};
my ContactListener.cpp is empty.
Xcode automatically handles building everything properly and things "just work". On Android, I had to specify my cpp files in Application.mk, so I wonder whether this could cause some different behaviour, because I am not specifying the .h files anywhere.
This is due to a bug in GB2ShapeCache.cpp provided by the PhysicsEditor file. While the boolean check for isSensor works in iOS / OS X , in Android it doesn't work as expected and sets it to false instead of true.
The fix:
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS
basicData.isSensor = (bool)static_cast<CCString *>(fixtureData->objectForKey("isSensor"))->intValue();
#else
CCString *foo = static_cast<CCString *>(fixtureData->objectForKey("isSensor"));
const char *s = foo->getCString();
if (s==NULL) {
basicData.isSensor = false;
}else{
std::string str(s);
if (str=="true") {
basicData.isSensor = true;
}else{
basicData.isSensor = false;
}
}
#endif