有没有一种简单的方法可以知道随机定位的对象是否最终会在另一个对象的顶部并在Physicsjs中触发碰撞?

时间:2014-03-25 23:03:52

标签: javascript game-physics physicsjs

我正在构建一个在画布内有随机定位对象的游戏。根据物体的数量,有可能将物体置于另一物体之上并触发碰撞检测。

在物理学js中有没有简单的方法来阻止这种情况?

2 个答案:

答案 0 :(得分: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...

执行此操作的另一种方法,即不太准确但效率更高的方法是检查身体的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
    }
}
希望有所帮助!

答案 1 :(得分:0)

我认为你应该有一个放置阶段,在此阶段你可以建立你的随机定位对象,然后是游戏的其他阶段。

在放置期间,您尝试随机添加对象并使用碰撞检测来决定是否必须再次尝试放置新的附加物,直到随机位置不会导致碰撞。

在后期阶段,您可以更改碰撞检测处理程序中的处理并执行您喜欢的操作。

在不同阶段替换处理程序,或区分某些模式变量发生的事情。

可能看起来很有趣,也许你可以这样做而不渲染物体或首先将物体渲染成白色,然后改变颜色。