the code is distributed in many files, but ill try to put here the minimum necesary.
A lot of info is missing in this semi code, since im using a lot of helper classes and utils. But this is actually all you need ( the player , children, and physics settings)
The character class
class PhysicsCharacter : public virtual cocos2d::Node
{
public:
~PhysicsCharacter();
virtual void AttachBody(const std::string& bodyName, cocos2d::PhysicsBody * body);
cocos2d::PhysicsBody* CreateCircleBody(
ColliderTags tag,
float radius = 50.0f,
const cocos2d::Vec2 offset = cocos2d::Vec2::ZERO,
bool isDynamic = true,
bool isSensor = false
);
protected:
cocos2d::Sprite* display;
//colliders
cocos2d::PhysicsBody* bodyMov;
// helper colliders
cocos2d::PhysicsBody* bodyHelperL;
cocos2d::PhysicsBody* bodyHelperR;
cocos2d::PhysicsBody* bodyHelperTL;
cocos2d::PhysicsBody* bodyHelperTR;
std::map<std::string, cocos2d::PhysicsBody*> bodiesByName;
};
The character init
bool PhysicsCharacter ::Init()
{
if(display = Sprite::CreateWithTexture("blabla.png")) <------ pseudocode
{
bodyMov = CreateCircleBody(_TAG::PLAYER, 50.0f, { 0,40 });
AttachBody("player", bodyMov);
bodyHelperTL = CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { -35,75 }, false, true); // ~ dynamic , sensor
bodyHelperTR = CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { 35,75 }, false, true); // ~ dynamic , sensor
bodyHelperL = CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { -35, 5 }, false, true); // ~ dynamic , sensor
bodyHelperR = CreateCircleBody(_TAG::PLAYER_HELPER, 35.0f, { 35, 5 }, false, true); // ~ dynamic , sensor
AttachBody("helper", bodyHelperL);
AttachBody("helper", bodyHelperR);
AttachBody("helper", bodyHelperTL);
AttachBody("helper", bodyHelperTR);
return true;
}
return false;
}
character - CreateBody:
cocos2d::PhysicsBody * PhysicsCharacter::CreateCircleBody(ColliderTags tag, float radius, const cocos2d::Vec2
offset, bool isDynamic, bool isSensor)
{
cocos2d::PhysicsBody* body = cocos2d::PhysicsBody::create();
auto shape = cocos2d::PhysicsShapeCircle::create(radius);
body->addShape(shape);
body->setPositionOffset(offset);
body->setDynamic(isDynamic);
shape->setSensor(isSensor);
body->setAngularDamping(0.0f);
body->setLinearDamping(0.0f);
body->setRotationEnable(false);
/// collision masks settings here
return body;
}
character - Attach body
void PhysicsCharacter::AttachBody(const std::string& bodyName, cocos2d::PhysicsBody * body)
{
if(tag == _TAG::PLAYER_HELPER)
{
auto child = cocos2d::Node::create();
addChild(child);
child->setPhysicsBody(body);
}
else
{
setPhysicsBody(body);
}
body->retain();
bodiesByName.insert({ bodyName ,body }); // keep a reference by name
}
The scene setup
Scene::Initialize
{
getPhysicsWorld()->setAutoStep(false);
//getPhysicsWorld()->setSubsteps(4); <<---- previous tests. result: FAIL
//getPhysicsWorld()->setUpdateRate(120); <<---- previous tests. result: FAIL
getPhysicsWorld()->setSpeed(5.0f);
getPhysicsWorld()->setGravity(Vec2(0, -98));
getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
schedule(schedule_selector(GS_1::update), 1.0f / 60.0f); // default Node::update
schedule(schedule_selector(GS_1::Update), 1.0f / 90.0f); // physics & logic
CHARACTER = PhysicsCharacter::Create();
if(CHARACTER )
{
CHARACTER ->setPosition(250, 180);
actionLayer->addChild(CHARACTER );
cameraTarget = CHARACTER ;
}
}
void Scene::update(float dt)
{
if(cameraTarget)
{
auto targetPos = cameraTarget->getPosition();
UI->setPosition(targetPos);
getDefaultCamera()->setPosition(targetPos);
}
getDefaultCamera()->update(dt);
Node::update(dt);
}
void Scene::Update(float dt)
{
for(int i = 0; i < 4; i++)
{
getPhysicsWorld()->step(dt);
}
actionLayer->update(dt);
}