Cocos2d iphone 如何在cocos2d(box2d)中检测反弹圆体与静态长方体的碰撞

Cocos2d iphone 如何在cocos2d(box2d)中检测反弹圆体与静态长方体的碰撞,cocos2d-iphone,box2d,Cocos2d Iphone,Box2d,嗨,朋友们,我对弹跳的圆形物体和运动的长方体的碰撞检测有问题。在我的游戏中,弹跳的圆形物体会接触到运动物体,有很多次弹跳的圆形物体不会与长方体碰撞,返回弹跳。有时会发生碰撞。我用我的知识搜索和尝试了很多,但没有结果。无论如何,请给我这个任务的解决方案。提前谢谢 CCSprite *_ball = [CCSprite spriteWithFile:@"Red Ball.png" ]; _ball.position = ccp(550, 150); _ball.tag=100; [self

嗨,朋友们,我对弹跳的圆形物体和运动的长方体的碰撞检测有问题。在我的游戏中,弹跳的圆形物体会接触到运动物体,有很多次弹跳的圆形物体不会与长方体碰撞,返回弹跳。有时会发生碰撞。我用我的知识搜索和尝试了很多,但没有结果。无论如何,请给我这个任务的解决方案。提前谢谢

  CCSprite *_ball = [CCSprite spriteWithFile:@"Red Ball.png" ];
 _ball.position = ccp(550, 150);
 _ball.tag=100;
 [self addChild:_ball];

 // Create ball body and shape
 b2BodyDef ballBodyDef;
 ballBodyDef.type = b2_dynamicBody;
 ballBodyDef.position.Set(470/PTM_RATIO, 120/PTM_RATIO);
 ballBodyDef.userData = _ball;
 _body = world->CreateBody(&ballBodyDef);

b2CircleShape circle;
circle.m_radius = 8.0/PTM_RATIO;

b2FixtureDef ballShapeDef;
ballShapeDef.shape = &circle;
ballShapeDef.density = 1.0f;
ballShapeDef.friction = 0.2f;
ballShapeDef.restitution = 0.8f;
_body->CreateFixture(&ballShapeDef);
_body->SetBullet(true);
_body->ApplyForce( b2Vec2(-80,20), _body->GetWorldCenter());


//Kinetic box body
CCSprite* oneRun=[CCSprite spriteWithFile:@"1RunImage.png"];
    [self addChild:oneRun];
    oneRun.tag=1;
    // Create wickets body and shape
    b2BodyDef fnt1runBodyDef;
    fnt1runBodyDef.type = b2_kinematicBody;
    fnt1runBodyDef.position.Set(size.width/PTM_RATIO, 30.0f/PTM_RATIO);
    fnt1runBodyDef.userData = oneRun;
    v1Body = world->CreateBody(&fnt1runBodyDef);

    b2PolygonShape run1box;
    //circle.m_radius = 13.0/PTM_RATIO;

    b2FixtureDef box1ShapeDef;
    box1ShapeDef.shape = &run1box;
    box1ShapeDef.density = .3f;
    run1box.SetAsBox(10.0f/PTM_RATIO,38.0f/PTM_RATIO);
    //ballShapeDef.friction = 0.2f;
    //box1ShapeDef.restitution = 0.5f;
    v1Body->CreateFixture(&box1ShapeDef);
用于碰撞Cantact listner

      // Loop through all of the Box2D bodies in our Box2D world..
for(b2Body *b = world->GetBodyList(); b; b=b->GetNext()) {

    // See if there's any user data attached to the Box2D body
    // There should be, since we set it in addBoxBodyForSprite
    if (b->GetUserData() != NULL) {

        // We know that the user data is a sprite since we set
        // it that way, so cast it...
        CCSprite *sprite = (CCSprite *)b->GetUserData();

        // Convert the Cocos2D position/rotation of the sprite to the Box2D position/rotation
        b2Vec2 b2Position = b2Vec2(sprite.position.x/PTM_RATIO,
                                   sprite.position.y/PTM_RATIO);
        float32 b2Angle = -1 * CC_DEGREES_TO_RADIANS(sprite.rotation);

        // Update the Box2D position/rotation to match the Cocos2D position/rotation
        b->SetTransform(b2Position, b2Angle);
    }
}

// Loop through all of the box2d bodies that are currently colliding, that we have
// gathered with our custom contact listener...
std::vector<b2Body *>toDestroy;
std::vector<MyContact>::iterator pos;
for(pos = contactlistener->_contacts.begin(); pos != contactlistener->_contacts.end(); ++pos) {
    MyContact contact = *pos;

    // Get the box2d bodies for each object
    b2Body *bodyA = contact.fixtureA->GetBody();
    b2Body *bodyB = contact.fixtureB->GetBody();

    if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
        CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
        CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();

        // Is sprite A a ball and sprite B a wicket?  If so, push the bat on a list to be destroyed...
        if (spriteA.tag == 100 && spriteB.tag == 1) {
            toDestroy.push_back(bodyA);


        }
        // Is sprite A a wicket and sprite B a ball?  If so, push the bat on a list to be destroyed...
        else if (spriteA.tag == 1 && spriteB.tag ==100) {
            toDestroy.push_back(bodyB);

            score=score+1;
            [scoreLable setString:[NSString stringWithFormat:@"Score: %i",score]];


        }
    }
}

// Loop through all of the box2d bodies we wnat to destroy...
std::vector<b2Body *>::iterator pos2;
for(pos2 = toDestroy.begin(); pos2 != toDestroy.end(); ++pos2) {
    b2Body *body = *pos2;

    // See if there's any user data attached to the Box2D body
    // There should be, since we set it in addBoxBodyForSprite
    if (body->GetUserData() != NULL) {

        // We know that the user data is a sprite since we set
        // it that way, so cast it...
        CCSprite *sprite = (CCSprite *) body->GetUserData();

        // Remove the sprite from the scene
        [self removeChild:sprite cleanup:YES];
    }

    // Destroy the Box2D body as well
    world->DestroyBody(body);
    //        [self unschedule:@selector(ballCreation)];



}

// If we've destroyed anything, play an amusing and malicious sound effect!  ;]
if (toDestroy.size() > 0) {
    //  [[SimpleAudioEngine sharedEngine] playEffect:@"hahaha.caf"];
}
//循环浏览我们Box2D世界中的所有Box2D实体。。
对于(b2Body*b=world->GetBodyList();b;b=b->GetNext()){
//查看是否有任何用户数据附加到Box2D主体
//应该有,因为我们在addBoxBodyForSprite中设置了它
如果(b->GetUserData()!=NULL){
//我们知道用户数据是一个精灵,因为我们设置了
//那样的话,就投吧。。。
CCSprite*sprite=(CCSprite*)b->GetUserData();
//将精灵的Cocos2D位置/旋转转换为Box2D位置/旋转
b2Vec2 b2Position=b2Vec2(sprite.position.x/PTM_比率,
雪碧位置y/PTM_比);
float32 b2Angle=-1*CC_度到_弧度(精灵旋转);
//更新Box2D位置/旋转以匹配Cocos2D位置/旋转
b->SetTransform(b2Position,b2Angle);
}
}
//循环通过当前正在碰撞的所有box2d实体,我们已经
//与我们的自定义联系人侦听器一起收集。。。
std::矢量编码;
std::vector::iterator pos;
对于(pos=contactlistener->_contacts.begin();pos!=contactlistener->_contacts.end();++pos){
MyContact contact=*位置;
//获取每个对象的box2d实体
b2Body*bodyA=contact.fixtureA->GetBody();
b2Body*bodyB=contact.fixtureB->GetBody();
如果(bodyA->GetUserData()!=NULL&&bodyB->GetUserData()!=NULL){
CCSprite*spriteA=(CCSprite*)bodyA->GetUserData();
CCSprite*spriteB=(CCSprite*)bodyB->GetUserData();
//精灵A是一个球,精灵B是一个边门吗?如果是的话,把球棒放在一张要摧毁的名单上。。。
if(spriteA.tag==100&&spriteB.tag==1){
toDestroy.向后推(bodyA);
}
//雪碧A是一个边门,雪碧B是一个球吗?如果是的话,把球棒放在一张要摧毁的名单上。。。
else if(spriteA.tag==1&&spriteB.tag==100){
toDestroy.向后推(车身B);
分数=分数+1;
[scoreLable设置字符串:[NSString stringWithFormat:@“分数:%i”,分数];
}
}
}
//通过我们想要摧毁的所有box2d尸体循环。。。
std::vector::迭代器pos2;
for(pos2=toDestroy.begin();pos2!=toDestroy.end();+pos2){
b2Body*body=*pos2;
//查看是否有任何用户数据附加到Box2D主体
//应该有,因为我们在addBoxBodyForSprite中设置了它
如果(body->GetUserData()!=NULL){
//我们知道用户数据是一个精灵,因为我们设置了
//那样的话,就投吧。。。
CCSprite*sprite=(CCSprite*)body->GetUserData();
//从场景中移除精灵
[自移除儿童:精灵清理:是];
}
//同时销毁Box2D车身
世界->毁灭身体(身体);
//[自我计划外:@selector(ballCreation)];
}
//如果我们破坏了任何东西,播放一个有趣而恶意的音效!;]
如果(toDestroy.size()>0){
//[[SimpleAudioEngine sharedEngine]播放效果:@“hahaha.caf”];
}

您是否通过启用调试绘图(glesdebug文件)来验证形状是否彼此接近?是的,我通过调试绘图验证了其接触,但没有碰撞检测,这就是为什么反弹圆是反向反弹的。