2011-04-14 32 views
1

我做了一个简单的游戏。检测box2d中钻石形状的问题

它有许多钻石形象和一个球。当球触摸钻石形状,然后发生碰撞。在我的应用中,当球碰到边缘时碰撞工作正常,但是当球碰到角落时,碰撞不起作用。

代码是听..

- (id)init { 

if ((self=[super init])) { 

    CGSize winSize = [CCDirector sharedDirector].winSize; 

    self.isTouchEnabled = YES; 

    self.isAccelerometerEnabled=YES; 
    // Create a world 
    b2Vec2 gravity = b2Vec2(0.0f, 0.0f); 
    bool doSleep = true; 
    _world = new b2World(gravity, doSleep); 

    // Create edges around the entire screen 
    b2BodyDef groundBodyDef; 
    groundBodyDef.position.Set(0,0); 
    _groundBody = _world->CreateBody(&groundBodyDef); 
    b2PolygonShape groundBox; 
    b2FixtureDef groundBoxDef; 
    groundBoxDef.shape = &groundBox; 
    groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(winSize.width/PTM_RATIO, 0)); 
    _bottomFixture = _groundBody->CreateFixture(&groundBoxDef); 
    groundBox.SetAsEdge(b2Vec2(0,0), b2Vec2(0, winSize.height/PTM_RATIO)); 
    _groundBody->CreateFixture(&groundBoxDef); 
    groundBox.SetAsEdge(b2Vec2(0, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO)); 
    _groundBody->CreateFixture(&groundBoxDef); 
    groundBox.SetAsEdge(b2Vec2(winSize.width/PTM_RATIO, winSize.height/PTM_RATIO), b2Vec2(winSize.width/PTM_RATIO, 0)); 
    _groundBody->CreateFixture(&groundBoxDef); 

    // Create sprite and add it to the layer 
    CCSprite *ball = [CCSprite spriteWithFile:@"ball1.png" rect:CGRectMake(0, 0, 16,16)]; 
    // ball.position = ccp(180, 400); 
    ball.tag = 1; 

// Create ball body 
    b2BodyDef ballBodyDef; 
    ballBodyDef.type = b2_dynamicBody; 
    ballBodyDef.position.Set(180/PTM_RATIO, 450/PTM_RATIO); 
    ballBodyDef.userData = ball; 
    ballBody = _world->CreateBody(&ballBodyDef); 

    // Create circle shape 
    b2CircleShape circle; 
    circle.m_radius = 16/PTM_RATIO; 
    //circle.m_radius = 50/PTM_RATIO; 

    // Create shape definition and add to body 
    b2FixtureDef ballShapeDef; 
    ballShapeDef.shape = &circle; 
    ballShapeDef.density = 1.0f; 
    ballShapeDef.friction = 0.0f; // We don't want the ball to have friction! 
    ballShapeDef.restitution = 0.0f; 
    _ballFixture = ballBody->CreateFixture(&ballShapeDef); 

    // Give shape initial impulse... 
    b2Vec2 force = b2Vec2(0, 0); 
    ballBody->ApplyLinearImpulse(force, ballBodyDef.position); 

    for(int i = 0; i < 5; i++) 


    { 
     static int padding=25; 



     CCSprite *block = [CCSprite spriteWithFile:@"diamond2.png"]; 
     int xOffset = padding+block.contentSize.width/5+((block.contentSize.width+padding)*i); 
     block.position = ccp(xOffset, 250); 
     block.tag = 2; 
     [self addChild:block]; 


     // Create block body 
     b2BodyDef blockBodyDef; 
     // blockBodyDef.type = b2_dynamicBody; 
     blockBodyDef.position.Set(xOffset/PTM_RATIO, 400/PTM_RATIO); 
     blockBodyDef.userData = block; 

     b2Body *blockBody = _world->CreateBody(&blockBodyDef); 

     // Create block shape 
     b2PolygonShape blockShape; 
     blockShape.SetAsBox(block.contentSize.width/PTM_RATIO/8, 
          block.contentSize.height/PTM_RATIO/8 
          ); 

     // Create shape definition and add to body 
     b2FixtureDef blockshapeDef; 
     blockshapeDef.shape = &blockShape; 
     blockshapeDef.density = 0.0; 
     blockshapeDef.friction = 10.0; 
     blockshapeDef.restitution = 0.1f; 
     blockBody->CreateFixture(&blockshapeDef); 
    } 

    [self addChild:ball]; 

// Create contact listener 
    _contactListener = new MyContactListener(); 
    _world->SetContactListener(_contactListener); 

    [[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"background-music-aac.caf"]; 

    [self schedule:@selector(tick:)]; 

} 
return self; 

}

- (void)tick:(ccTime) dt { 

    // bool blockFound = false; 
_world->Step(dt, 10, 10);  
for(b2Body *b = _world->GetBodyList(); b; b=b->GetNext()) {  
    if (b->GetUserData() != NULL) { 
     CCSprite *sprite = (CCSprite *)b->GetUserData();  



     if (sprite.tag == 1) { 
      static int maxSpeed = 20; 

      b2Vec2 velocity = b->GetLinearVelocity(); 
      float32 speed = velocity.Length(); 

      // When the ball is greater than max speed, slow it down by 
      // applying linear damping. This is better for the simulation 
      // than raw adjustment of the velocity. 
      if (speed > maxSpeed) { 
       b->SetLinearDamping(0.2); 
      } else if (speed < maxSpeed) { 
       b->SetLinearDamping(0.0); 
      } 

     } 

     sprite.position = ccp(b->GetPosition().x * PTM_RATIO, 
           b->GetPosition().y * PTM_RATIO); 
     sprite.rotation = 1 * CC_RADIANS_TO_DEGREES(b->GetAngle()); 

} 
} 
} 

PLZ帮我检测接近菱形的一角正确collsion检测....

+0

你已经张贴了大量的代码。我建议只发布进行碰撞检测的部分。 – Gabe 2011-04-14 07:43:30

+0

我为您理解的具体代码做了评论.... – Jasmit 2011-04-14 09:12:11

+0

尝试发布*只是代码行不行*而不是150行代码,我们应该找出问题出在哪里。 – Gabe 2011-04-14 14:14:51

回答

1

我不是当然,我明白,但看起来你并没有制作钻石,你正在制作方块/方块:

blockShape.SetAsBox(block.contentSize.width/PTM_RATIO/8,block.contentSize.height/PTM_RATIO/8); 

也许这就是为什么你说碰撞不起作用。

如果你的身体是一个正方形,你的精灵是一个钻石有三个选项:

  • 或钻石具有相等的宽度和高度,这只是需要转动广场。这种碰撞应该没有问题。
  • 或者其他形状在不应该出现的情况下会在方形的(看不见的)角落碰撞(当精灵/钻石适合方形和正方形没有旋转或者金刚石具有宽度时!=需要定制形状的高度)
  • 或者其他形状不会与钻石精灵角落相撞(当方形较小并适合钻石精灵时)。

还有其他的方法来创建自定义形状,例如:

void b2PolygonShape::Set(const b2Vec2* vertices, int32 count) 
void b2PolygonShape::SetAsEdge(const b2Vec2& v1, const b2Vec2& v2)