2
\$\begingroup\$

I am trying to implement swipe and cut a sprite using cocos2dx and inbuilt chipmunk.

For the solution I have done following things

  1. Enabled physics in the scene, so that the body falls on cut.
  2. Used RayCast to cut the PhysicsBody. I am able to cut the PhysicsBody but not the Sprite. I want to do it with Sprite.

See my code below

void HelloWorld::startGame(float dt){
    LayerColor *pillar=LayerColor::create(Color4B::YELLOW, 100.0, winsize.height*.70);
    pillar->setPosition(Vec2(winsize.width*0.5,winsize.height*.15));
    this->addChild(pillar);

    Size size=pillar->getContentSize();

    PhysicsBody *physicsBody=PhysicsBody::createBox(size,PhysicsMaterial(1.0f,0.0,0.5f),Vec2::ZERO);
    physicsBody->setGravityEnable(false);
    pillar->setPhysicsBody(physicsBody);
    physicsBody->setCategoryBitmask(1);
    physicsBody->setCollisionBitmask(1);
    physicsBody->setContactTestBitmask(true);
    physicsBody->setDynamic(false);
    physicsBody->setContactTestBitmask(0xFFFFFFFF);

    //create a ground
    ground = Node::create();
    ground->setPhysicsBody(PhysicsBody::createEdgeSegment(VisibleRect::leftBottom() + Vec2(0, 0), VisibleRect::rightBottom() + Vec2(0, 0),PHYSICSBODY_MATERIAL_DEFAULT,5.0));
    this->addChild(ground);
    ground->setTag(BOUNDARY_TAG);
}

void HelloWorld::onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *event){
    auto func = CC_CALLBACK_3(HelloWorld::slice, this);

    Vec2 start=touch->getStartLocation();
    Vec2 end=touch->getLocation();

    end.y=start.y;

    _scene->getPhysicsWorld()->rayCast(func, start, end, nullptr);
}


bool HelloWorld::slice(PhysicsWorld &world, const PhysicsRayCastInfo& info, void *data)
{
    printf("\n sliced body tag = %d",info.shape->getBody()->getTag());

    if (info.shape->getBody()->getTag() != _sliceTag)
    {
        return true;
    }

    if (!info.shape->containsPoint(info.start) && !info.shape->containsPoint(info.end))
    {
        Vec2 normal = info.end - info.start;
        normal = normal.getPerp().getNormalized();
        float dist = info.start.dot(normal);

        clipPoly(dynamic_cast<PhysicsShapePolygon*>(info.shape), normal, dist);
        //clipPoly(dynamic_cast<PhysicsShapePolygon*>(info.shape), -normal, -dist);

        info.shape->getBody()->removeFromWorld();

        detectCollision=true;
    }

    return true;
}

void HelloWorld::clipPoly(PhysicsShapePolygon* shape, Vec2 normal, float distance)
{
    PhysicsBody* body = shape->getBody();
    int count = shape->getPointsCount();
    int pointsCount = 0;
    Vec2* points = new (std::nothrow) Vec2[count + 1];

    for (int i=0, j=count-1; i<count; j=i, ++i)
    {
        Vec2 a = body->local2World(shape->getPoint(j));
        float aDist = a.dot(normal) - distance;

        if (aDist < 0.0f)
        {
            points[pointsCount] = a;
            ++pointsCount;
        }

        Vec2 b = body->local2World(shape->getPoint(i));
        float bDist = b.dot(normal) - distance;

        if (aDist*bDist < 0.0f)
        {
            float t = std::fabs(aDist)/(std::fabs(aDist) + std::fabs(bDist));
            points[pointsCount] = a.lerp(b, t);
            ++pointsCount;
        }
    }

    Vec2 center = PhysicsShape::getPolyonCenter(points, pointsCount);
    Node* node = Node::create();
    PhysicsBody* polygon = PhysicsBody::createPolygon(points, pointsCount, PHYSICSBODY_MATERIAL_DEFAULT, -center);

    lastPillar->setPhysicsBody(polygon);
    polygon->setVelocity(body->getVelocityAtWorldPoint(center));
    polygon->setAngularVelocity(body->getAngularVelocity());
    polygon->setTag(NEW_PILLAR_TAG);
    addChild(node);
    polygon->setCategoryBitmask(1);
    polygon->setCollisionBitmask(1);
    polygon->setContactTestBitmask(true);
    polygon->setContactTestBitmask(0xFFFFFFFF);
    polygon->setMass(0.5f);

    delete[] points;
}

The above code perfectly cuts the PhysicsBody, How to do the same with the Sprite, or the Layer attached with the PhysicsBody.?

\$\endgroup\$
  • \$\begingroup\$ I'm not familiar with cocos2d, so I have a question. Do you have access to OpenGL functionality? If so, what version of it you have? \$\endgroup\$ – HolyBlackCat Apr 25 '15 at 13:07
  • \$\begingroup\$ @HolyBlackCat Since I am working on cocos2dx it uses OpenGL automatically, the version is OpenGL ES 2.0 APPLE-10.1.5 \$\endgroup\$ – iphonic Apr 25 '15 at 17:13
  • \$\begingroup\$ Since you have the two new physics bodies (after cut) why don't you just duplicate the sprite and truncate each one to fit a respective physics body? \$\endgroup\$ – StrongJoshua Apr 26 '15 at 17:39
  • \$\begingroup\$ @StrongJoshua Can you help with some code, how to accomplish this? Thanks. \$\endgroup\$ – iphonic Apr 27 '15 at 5:06
  • \$\begingroup\$ This tutorial explains slicing using Box2D emanueleferonato.com/2011/06/13/… . Note that it consists of several parts. \$\endgroup\$ – nikoliazekter Apr 28 '15 at 11:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.