Правильное удаление креплений Box2D и обновление b2Body - PullRequest
2 голосов
/ 03 февраля 2012

У меня есть тело Box2d, которое я пытаюсь разбить на несколько частей. Для этого я перебираю его приборы и генерирую новые тела для каждого. Используя отладочную отрисовку, я вижу, что это работает.

enter image description here

Как вы можете видеть на изображении выше, первичное тело разрушается и генерируется вторичное тело (помеченное как 2). Основываясь на рендеринге фигур из слоя отладки, они отображаются правильно. У меня проблема в том, что CCSprite, который я связываю с моим основным b2body, неправильно позиционируется по отношению к новому телу. Кажется, что связанный CCSprite позиционируется (с учетом точки привязки 0, 0), как если бы он все еще был частью более крупной формы.

Для справки, вот код, который я использую:

for (b2Fixture *f = body->GetFixtureList(); f; f = f->GetNext())
{
    NSString *newSpriteFrameName = (NSString *)f->GetUserData();

    // Steal some of our parent bodies properties
    b2BodyDef bd;
    bd.type = b2_dynamicBody;
    bd.position = [self physicsPosition];
    bd.angle = [self angle];

    b2Body *newBody = _world->CreateBody(&bd);

    b2FixtureDef fixtureDef;
    fixtureDef.shape = f->GetShape();
    fixtureDef.density = f->GetDensity();
    fixtureDef.restitution = f->GetRestitution();
    fixtureDef.friction = f->GetFriction();
    fixtureDef.userData = f->GetUserData();
    newBody->CreateFixture(&fixtureDef);

    // Try to transfer any angular and linear velocity
    b2Vec2 center1 = [self worldCenter];
    b2Vec2 center2 = newBody->GetWorldCenter();

    CGFloat angularVelocity = parentBody->GetAngularVelocity();
    b2Vec2 velocity1 = [self linearVelocity] + b2Cross(angularVelocity, center1 - center1);
    b2Vec2 velocity2 = [self linearVelocity] + b2Cross(angularVelocity, center2 - center1);

    newBody->SetAngularVelocity(angularVelocity);
    newBody->SetLinearVelocity(velocity2);

    // Create a new destructable entity
    CCSprite *newSprite = [CCSprite spriteWithSpriteFrameName:newSpriteFrameName];
    SIDestructableEntity *newEntity = [[SIDestructableEntity alloc] initWithBody:newBody node:newSprite];
    [[newEntity ccNode] setAnchorPoint:CGPointMake(0, 0)];
    [game.entities addObject:newEntity];
    [game.entityLayer addChild:[newEntity ccNode]];
}

Вот как я устанавливаю местоположение своих CCSprites для каждого логического тика:

b2Vec2 position = body->GetPosition();
ccNode.position = CGPointMake(PTM_RATIO*position.x, PTM_RATIO*position.y);
ccNode.rotation = -1 * CC_RADIANS_TO_DEGREES(body->GetAngle());

1 Ответ

0 голосов
/ 13 декабря 2013

Эта строка выглядит подозрительно.

[[newEntity ccNode] setAnchorPoint:CGPointMake(0, 0)];

Спрайт обычно имеет точку привязки (0.5,0.5).Если точка привязки вашего тела находится посередине (не видно из кода выше), тогда якорь (0.5,0.5) для спрайта также поместит его в середину.Установка его в (0,0) приводит к тому, что верхний левый угол спрайта помещается в положение спрайта.

Я предполагаю, что якорь вашего тела находится внизу слева от тела, а якорь спрайта - вверху справа, давая эффект, который вы видите.

...