Using BOX2D just for collision makes sprites get moved very fast

Using BOX2D just for collision makes sprites get moved very fast
0

Hi, I putted a physics body to all my sprites that I want to check for collision, but I really not want to use the other physics features like gravity, friction, etc just need a more precise collision than just checking for intersection between bounding boxes.

The thing is that when I set physicsworld and physicbodies my characters get moving very fast compared to the movement made without setting a physics world. I move them on the game with setPositionY(getPositionY + speed * dt) I mean no physic forces, is there a way to prevent what is happening? Please give me some help because I think that they are kinematic bodies and shouldn’t be affected this way by the physics but somehow they do and I can’t find the setting to prevent it, also the documentation is out of my understanding and it differs between classical BOX2D and the implementation of cocos2d-x of this library.

On my scene I set this:

#if _USE_PHYSICS == 1

if (!Scene::initWithPhysics())
        return false;

//getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
getPhysicsWorld()->setGravity(Vec2(0.0f, 0.0f));
getPhysicsWorld()->setSpeed(0.0f);

MyBodyParser::getInstance()->parseJsonFile("Physics");

#elif _USE_PHYSICS == 0

if (!Scene::init())
    return false;

#endif

and in my characters like this, I vary the 3 parameters for Physics Material but I see no difference:

if (!Sprite::initWithSpriteFrameName(_ENEMY_IDLE_PATH))
    return false;

#if _USE_PHYSICS == 1
    auto phBody = MyBodyParser::getInstance()->bodyFormJson(this, "Enemy", PhysicsMaterial(1.0f, 0.0f, 10.0f));
    phBody->setDynamic(false);
    phBody->setGravityEnable(false);
    this->setPhysicsBody(phBody);
#endif

and like this:

if (!Sprite::initWithSpriteFrame(SpriteFrameCache::getInstance()->getSpriteFrameByName(filename)))
    return false;

setVisible(false);

#if _USE_PHYSICS == 1

auto phBody = MyBodyParser::getInstance()->bodyFormJson(this,
                                                        (_type == UP_BULLET) ? "BulletPlayer" : "BulletEnemy",
                                                        PhysicsMaterial(10.0f, 0.0f, 10.0f));

phBody->setDynamic(false);
phBody->setGravityEnable(false);
this->setPhysicsBody(phBody);

#endif

Hope somebody could help, thanks.

Did a little search based on possible reasons and came up with this:

Inside Scene class:

void Scene::stepPhysicsAndNavigation(float deltaTime)
{
#if CC_USE_PHYSICS
    if (_physicsWorld && _physicsWorld->isAutoStep())
        _physicsWorld->update(deltaTime);
#endif

It looks like if isAutoStep() returns true, it will call the update function, and then you probably are running a scheduledUpdate as well, which would make update be called twice. This is potentially the issue, so you will need to make sure the _physicsWorld is not automatically calling the update function for you, or unschedule your own update.

Wow, that makes sense, I am going to check.

Thanks for your response.

It’s strange because if I unschedule the update of my scene on my class I get regular speed movement (as desired) on my characters but not in the parallax background (which remains stopped) should be moved in the update method of my scene by the code.

And if I instead comment the line which runs update on _physicsWorld that you gave me I get the same results of twice the speed.

what does the update() look like inside your scene? You can also use breakpoints here and see where/how things are being called where you don’t want them to be…

Like this man, I liked to keep the order of the individual objects all here instead of schedule their update methods apart:

void GameScene::update(float dt) {

    _UILayer->update(dt);

    static int hittedPlayerVal = plyr->getHitted();
    
    if (plyr->getHitted() != hittedPlayerVal) {
        hittedPlayerVal = plyr->getHitted();
        _UILayer->setHealthLabel(hittedPlayerVal);
    }
    
    if (plyr->isVisible())
        _bg->update(dt);


    if(d_Destroy / (_numEnemies / 4) > 0 && d_Destroy % (_numEnemies / 4) == 0){
        powerUpHealth->setVisible(true);
    }

    if (powerUpHealth->isVisible())
        powerUpHealth->update(dt);

    for (auto i : _enemyPool)
        i->update(dt);

    plyr->update(dt);
    
    if (plyr->getDestroyed() && gameState == PLAYING) {
        
        _UILayer->runActionDerrota();
        gameState = DEFEAT;
    }
    
    checkCollisionsBetweenCharacters();
}

I am going to keep checking as you say with breakpoints to see the order of the lines getting executed and find the one that is giving me trouble, definitively is something related to the way update is managed by physics that I do not understand.

Are you scheduling the update inside any of those player nodes? That would make it be called twice. Since you manually update them here. You can breakpoint inside the update function of one of the players and see if it is called twice per cycle.

Man, thanks for your attention, I have just one class more than has his update scheduled, if I comment it, I have no updates scheduled in my code.

Then if I run the program I note that I get calls referenced for all the update methods except for my scene, doesn’t suppose that without autostep then the update method shouldn’t schedule automatically? (Because I still get it) Or is there a complete guide of what implies to use physics on cocos2d-x?