0
votes

I'm working on a game in Cocos2d with Box2D. Currently I have a system set up where there are some boundaries. They are for a ball. I want meteors to come in from off the screen and smack the ball.

The boundaries are defined in my init method as follows:

    // Define the ground body.
    b2BodyDef groundBodyDef;
    groundBodyDef.type = b2_staticBody;
    groundBodyDef.position.Set(0, 0); // bottom-left corner

    // Call the body factory which allocates memory for the ground body
    // from a pool and creates the ground box shape (also from a pool).
    // The body is also added to the world.
    b2Body* groundBody = world->CreateBody(&groundBodyDef);

    // Define the ground box shape.
    b2PolygonShape groundBox;       

    // bottom
    groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(screenSize.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);

    // top
    groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO));
    groundBody->CreateFixture(&groundBox,0);

    // left
    groundBox.SetAsEdge(b2Vec2(0,screenSize.height/PTM_RATIO), b2Vec2(0,0));
    groundBody->CreateFixture(&groundBox,0);

    // right
    groundBox.SetAsEdge(b2Vec2(screenSize.width/PTM_RATIO,screenSize.height/PTM_RATIO), b2Vec2(screenSize.width/PTM_RATIO,0));
    groundBody->CreateFixture(&groundBox,0);

    //Collision filter stuff here. Not working.
    b2Filter filter;
    filter.groupIndex = -2;
    groundBody->GetFixtureList()[0].SetFilterData(filter);

My ball is defined as follows:

    //Physics object.
    b2BodyDef ballBodyDef;
    ballBodyDef.position.Set(ball.position.x/PTM_RATIO, ball.position.y/PTM_RATIO);
    ballBodyDef.type = b2_dynamicBody;
    ballBodyDef.userData = ball;
    ballBodyDef.bullet = true;
    ballBody = world->CreateBody(&ballBodyDef);

    b2CircleShape ballShape;
    ballShape.m_radius = 10.0/PTM_RATIO;
    b2FixtureDef ballFix;
    ballFix.restitution = 1.1f;
    ballFix.density  = 0.0f;
    ballFix.shape = &ballShape;
    ballBody->CreateFixture(&ballFix);

And the meteors are made using two methods, the shorter method places the meteors. The longer one actually creates them using the points given from the shorter one:

-(void)createMeteorAtPoint:(CGPoint)point {
    //Create particle sprite representation.
    CCParticleMeteor *meteor = [[CCParticleMeteor alloc] initWithTotalParticles:200];
    meteor.gravity = ccp(-200,0);
    meteor.life = 0.5;
    meteor.lifeVar = 0.25;
    meteor.position = point;
    meteor.tag = 2;
    meteor.startSize = 5.0;
    meteor.startSizeVar = 3.0;
    [self addChild:meteor];

    //Make meteor physics body.    
    b2BodyDef meteorBodyDef;
    meteorBodyDef.position.Set(point.x/PTM_RATIO, point.y/PTM_RATIO);
    meteorBodyDef.type = b2_dynamicBody;
    meteorBodyDef.userData = meteor;
    b2Body *meteorBody = world->CreateBody(&meteorBodyDef);
    meteorBody->SetBullet(true);

    b2CircleShape meteorShape;
    meteorShape.m_radius = 7.5/PTM_RATIO;
    b2FixtureDef meteorFix;
    meteorFix.shape = &meteorShape;
    meteorFix.density = 1;

    //Give it the same negative group index of the boundaries to prevent collision.
    //Not working.
    meteorFix.filter.groupIndex = -2;

    meteorBody->CreateFixture(&meteorFix);

    //Give it a motion.
    b2Vec2 F;
    F.Set(CCRANDOM_0_1()*2, 0);
    meteorBody->SetLinearVelocity(F);
}

//Create a bunch of meteors that will sweep from left to right.
-(void)createMeteors {
    for (int i = 0; i < 8*40; i += 20) {
        [self createMeteorAtPoint:ccp(-40.0f, i + 2)];
    }
    NSLog(@"HERE");
}

I can see physics objects pile up on the side of the screen because I have debug flags set up. But one: They are not getting past the boundary despite being the same negative group index. And two: the ball decides it doesn't like the right wall, and goes through it.

If you believe I am missing something crucial please tell me.

1

1 Answers

1
votes

Only one of the boundary fixtures is being given the group index of -2 (the bottom). You can loop over all fixtures of a body like this:

for (b2Fixture* f = body->GetFixtureList(); f; f = f->GetNext())
{
    //do something with the fixture 'f'
    f->SetFilterData(...);
}

I'm not sure why the ball would be ignoring any walls though (unless you are moving it by creating a mouse joint between the ball and the ground body that the walls belong to, and the joint is set to not collide connected bodies... but in that case the ball would ignore all walls, and only while being moved).