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...

另一种不太准确但更有效的方法是检查物体的 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 回答