0

このコードが 1 回呼び出された後、box2d 物理シミュレーションが永遠に途切れるコードがあります。パフォーマンス テストを実行しましたが、OSSpinLockLock には多くの時間が費やされました。b2Island::Solve と他のいくつかの box2d 関数が、これに非常に多くの時間を費やしています。ここで何が起こっているのかよくわかりません。この影響は、スタティック ボディのオーバーラップが少ないマップよりもスタティック ボディのオーバーラップが多いマップの方が悪いようです。吃音を引き起こすコードは次のとおりです。

for (b2Body*b = currentWorld->GetBodyList(); b!=nil; b = b->GetNext()) {



    float distance = 0;
    float strength = 0;
    float force = 0;
    float angle = 0;

    CGPoint curPos = [Helper toPixels:b->GetWorldCenter()];

    distance = ccpDistance(selfPos, curPos);
    if (distance>maxDistance) {
        distance = maxDistance - 0.01;
    }

    //strength = (maxDistance - distance) / maxDistance;
    strength = (distance - maxDistance)/maxDistance;
    force = strength * maxForce;
    angle = atan2f(selfPos.y - curPos.y, selfPos.x - curPos.x);
    //b2Vec2 forceVec = [Helper toMeters:force];

    //CCLOG(@"strength = %f force = %f angle = %f distance = %f",strength,angle,force, distance);
    b->ApplyLinearImpulse(b2Vec2(cosf(angle) * force, sinf(angle) * force), b->GetPosition());
    BodyNode * bn = (BodyNode*)b->GetUserData();
    if ([bn isKindOfClass:[Soldier class]]) {
        ((Soldier*)bn).health-=abs(force*(damage * kRocketDamageFactor)); //used to be 50
    }
    if ([bn isKindOfClass:[BaseAI class]]) {
        ((BaseAI*)bn).health-=abs(force*(damage * kRocketDamageFactor));
    }
    if ([bn isKindOfClass:[BaseLevelObject class]]) {
        if (((BaseLevelObject*)bn).takesDamageFromBullets == YES) {
            ((BaseLevelObject*)bn).health-=abs(force*(damage * kRocketDamageFactor));
        }

    }

ApplyLinearImpulse 部分が物理に関連する唯一のものであるため、スタッターの原因であると思われます。このループ全体をコメントアウトしただけで、スタッターは発生しませんでした。しかし、同じコードで他の爆発物を爆発させるとすぐに、スタッターが発生しました。重なり合う静的 b2body オブジェクトは物理シミュレーションの速度を低下させますか?

4

1 に答える 1

0

この問題は、コードが最大距離よりも遠くにあるすべての物体に爆発に向かって小さなタップを与えることによって引き起こされました。これにより物理シミュレーションが途切れる理由はよくわかりませんが、continue ステートメントを distance = maxDistance - 0.01; の代わりに追加します。問題を解決しました。

于 2012-06-15T00:01:48.893 に答える