0

キャンバス内にランダムに配置されたオブジェクトを持つゲームを構築しています。オブジェクトの量によっては、オブジェクトが他のオブジェクトの上に配置され、衝突検出がトリガーされる合理的な可能性があります。

物理jsでこれを防ぐ簡単な方法はありますか?

4

2 に答える 2

1

これを行うにはいくつかの方法があります。

最初の (そして最も堅牢な): 衝突検出モジュールを追加できますが、衝突応答は追加できません。次に、衝突イベントをリッスンし、必要に応じて削除して再度追加します。

例えば:

function removeOverlaps( data ){
    var collisions = data.collisions
        ,col
        ,removed = []
        ;
    for ( var i = 0, l = collisions.length; i < l; ++i ){

        col = collisions[ i ];
        // ensure that we haven't removed one of the bodies before
        if ( Physics.util.indexOf(removed, col.bodyA ) === -1 &&
            Physics.util.indexOf(removed, col.bodyB ) === -1
        ){
            // pick bodyA... why not...
            removed.push( col.bodyA );
            world.remove( col.bodyA );
        }
    }
}
world.add(Physics.behavior('body-collision-detection'));
world.subscribe('collisions-detected', removeOverlaps);

var tries = 0;
while( tries < maxTries ){
    addBodies();
    world.step(tries); // "tries" pretends to be a timestamp
    if ( world.getBodies().length >= bodiesWeNeed ){
        break;
    }
    tries++;
}

world.unsubscribe('collisions:detected', removeOverlaps);
// continue with simulation...

これを行うもう 1 つの方法は、精度は劣りますがより効率的であり、ボディの AABB が重複しているかどうかを確認することです。

function checkOverlap( bodyA, bodyB ){
    var aabbA = bodyA.aabb()
        ,aabbB = bodyB.aabb()
        ;

    // check if the aabb has separation on the x axis
    if ( 
        (aabbA.pos.x + aabbA.halfWidth) < (aabbB.pos.x - aabbB.halfWidth)||
        (aabbB.pos.x + aabbB.halfWidth) < (aabbA.pos.x - aabbA.halfWidth)
    ){
        return true;
    }

    if ( 
        (aabbA.pos.y + aabbA.halfHeight) < (aabbB.pos.y - aabbB.halfHeight)||
        (aabbB.pos.y + aabbB.halfHeight) < (aabbA.pos.y - aabbA.halfHeight)
    ){
        return true;
    }

    return false;
}

while( numBodies < maxBodies ){
    var newBody = makeBody();
    var toAdd = true;
    for (//each body in added bodies)
        if ( checkOverlap(newBody, body) ){
            toAdd = false;
            break;
        }
    }

    if ( toAdd ){
         world.add( newBody ); // and maybe add to a list you keep
    }
}

それが役立つことを願っています!

于 2014-03-26T14:52:42.890 に答える
0

ランダムに配置されたオブジェクトを構築する配置フェーズが必要であり、その後、ゲームの他のフェーズが必要だと思います。

配置中に、オブジェクトをランダムに追加しようとし、衝突検出を使用して、ランダムな位置が衝突につながらなくなるまで、新しい追加の配置を再試行する必要があるかどうかを決定します。

後のフェーズでは、衝突検出ハンドラーの処理を変更し、好きなことを行います。

さまざまなフェーズでハンドラーを置き換えるか、モード変数によって何が起こるかを区別してください。

おかしく見えるかもしれませんが、オブジェクトをレンダリングせずにこれを行うか、最初にオブジェクトを白地に白くレンダリングしてから色を変更することができます。

于 2014-03-25T23:16:08.227 に答える