0

Box2D を使用して Cocos2d でゲームを作成しています。現在、いくつかの境界があるシステムをセットアップしています。ボール用です。画面の外から流星が入ってきて、ボールを叩いてほしいです。

境界は私の init メソッドで次のように定義されています。

    // 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);

私のボールは次のように定義されています。

    //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);

そして、流星は2つの方法を使用して作られ、短い方が流星を配置します。長いものは、短いものから与えられたポイントを使用して実際にそれらを作成します。

-(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");
}

デバッグ フラグを設定しているため、画面の横に物理オブジェクトが山積みになっているのがわかります。しかし 1 つ: 同じ負のグループ インデックスであるにもかかわらず、境界を越えていません。そして 2 つ目は、ボールが右の壁が気に入らないと判断し、それを通過することです。

私が決定的な何かを見逃していると思われる場合は、教えてください。

4

1 に答える 1

1

境界フィクスチャの 1 つだけにグループ インデックス -2 (下) が与えられています。次のように、ボディのすべてのフィクスチャをループできます。

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

ただし、ボールが壁を無視する理由はわかりません(ボールと壁が属するグラウンドボディの間にマウスジョイントを作成してボールを動かし、ジョイントが接続されたボディに衝突しないように設定されている場合を除きます.. .しかしその場合、ボールはすべての壁を無視し、移動中のみ)。

于 2012-09-15T00:19:17.210 に答える