Search code examples
touchbox2dphysicscocos2d-x

How to detect a touch inside a box2d fixture created by PhyicsEditor in Cocos2d-x?


My testing environment:

Xcode 4.6, New cocos2d-x+box2d project cocos2d-2.1beta3-x-2.1.1 PhysicsEditor 1.0.10

I modified a bit in HelloWorldScene of PhysicsEditor cocos2dx demo to make it simpler, Here are some of my code:

  1. initPhysics

    gravity.Set(0.0f, 0.0f);

So that the sprite will not move.

  1. Replace source code inside ccTouchesEnded to:

    CCTouch* pTouch = (CCTouch *)touches->anyObject();

    CCPoint location = pTouch->locationInView(pTouch->view());

    CCPoint convLoc = CCDirector::sharedDirector()->convertToGL(location);

    b2Vec2 v = b2Vec2(convLoc.x/PTM_RATIO, convLoc.y/PTM_RATIO);

    for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()) {

    b2Fixture *f = b->GetFixtureList(); // get the first fixture
    CCSprite *sprite =(CCSprite *) b->GetUserData();
    
    if(sprite != NULL)
    {
        if(f -> TestPoint(v))
        {
            CCLog("You touched a body %d",sprite->getTag());
        }
    }
    

    }

The problem is that TestPoint only return true in a very small area (not for whole shape area).

Here is the screenshot:

enter image description here

Can anybody suggest how I debug this problem? Thanks

Updated: showing the generated data from PhysicsEditor

enter image description here


Solution

  • The problem is that you only probe for the first fixture. But complex bodies are made from several. The reason is that

    • Box2d only allows 8 vertexes per fixture
    • Box2d can only work with convex shapes

    This is why complex shapes are decomposed into a list of polygons.

    Iterate over the fixture list instead.

    b2Fixture *f = body->GetFixtureList();
    while(f)
    {
        if(f -> TestPoint(v))
        {
            CCLog("You touched a body %d",sprite->getTag());
        }
        f = f->GetNext();            
    }