Chipmunk collision

I’m trying move a simple sprite and make then stop when collide on other objects or edges scene.

For move the sprite i use MoveBy , but if the movement was bigger than edge he will cross the edge.

example:

 auto edgeBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT ,3);
 this->addComponent(edgeBody);

 auto sprite = Sprite::create("img.png");
 sprite->setPosition(NearTheEdge);

 auto mBody = PhysicsBody::createBox(this->getContentSize());
 
 sprite->addComponent(mBody);
 this->addChild(sprite);

 sprite->runAction(MoveBy::create(0.0f,Vec3(20.0f,0.0f,0.0f))); // it will cross the edge

 // or i can do..
 sprite->setPosition(this->getPosition().x +20, this->getPosition().y); // obvious will cross

have any way to make it work appropriately?

Then problem is that many physics engines (including Chipmunk) don’t do Continuous Collision Detection. You have several approaches to “fix” the issue. You can use smaller time steps for your collision detection, you can use ray casting for your objects, or use Box2D instead of Chipmunk which supports CCD.

To use chipmunk collisions properly you use applyForce to objects so chipmunk can calculate when a collision will occur try this and see if it helps

Unfortune my problem is move a player and monsters. I can’t do it using applyForce.

I try enable Box2D in my cocos2d-x, but i’m using linux and lot off errors occurs when i try it.

You can use impulse or add velocities to the player (although I heard that Chipmunk doesn’t like it when you manually mess with the velocities, but if it works in your case, don’t hesitate to use it!). Manually setting the player to a position, without using one of the physics engine options (force, acceleration, impulse, velocity) is never a good option when working with collision detection and… a physics engine.

You can also increase the collision box on your items so that they are at least one pixel bigger than the steps you take. Or, as I suggested, simply decrease the update time to have more checks, unless you really, really use high velocities.

i’m testing box2d now :smiley:
if solve my problem i will post here a solution.

i solve my problem using setVelocity

void PlayerSprite::MoveUP(bool active)
{
    if (active){
        activeUP = true;
        this->getPhysicsBody()->setVelocity(Vec2(this->getPhysicsBody()->getVelocity().x,100));
    } else{
        if (activeUP)
        {
            this->getPhysicsBody()->setVelocity(Vec2(0,0));
            activeUP = false;
        }
    }
}

void PlayerSprite::MoveDOWN(bool active)
{
   if (active) {
       activeDOWN = true;
       this->getPhysicsBody()->setVelocity(Vec2(this->getPhysicsBody()->getVelocity().x,-100));
   }else {
       if (activeDOWN)
       {
           this->getPhysicsBody()->setVelocity(Vec2(0,0));
           activeDOWN = false;
       }
   }
}

void PlayerSprite::MoveLEFT(bool active)
{
    if (active){
        activeLEFT = true;
         //mBodyPlayer->setVelocityLimit(1000.0f);
        this->getPhysicsBody()->setVelocity(Vec2(-100,this->getPhysicsBody()->getVelocity().y));
    } else {
        if (activeLEFT)
        {
            this->getPhysicsBody()->setVelocity(Vec2(0,0));
            activeLEFT = false;
        }
    }
}

void PlayerSprite::MoveRIGHT(bool active)
{
    if (active){
        activeRIGHT = true;
        this->getPhysicsBody()->setVelocity(Vec2(100,this->getPhysicsBody()->getVelocity().y));
    }else{
        if (activeRIGHT)
        {
            this->getPhysicsBody()->setVelocity(Vec2(0,0));
            activeRIGHT = false;
        }
    }
}

probably is not the best solution but work’s for me. thanks for help