我正在构建一个在画布内随机定位对象的游戏。根据物体的数量,有一个合理的机会将一个物体放置在另一个物体的顶部,并触发碰撞检测。
是否有任何简单的方法来防止这种物理js?
有几种方法可以做到这一点。
第一(也是最健壮的):您可以添加碰撞检测模块,但不能添加碰撞响应。然后监听碰撞事件,必要时删除并重新添加。
,
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
}
}
希望有帮助!
我认为你应该有一个放置阶段,在那里你建立你的随机定位的对象,然后你的游戏的其他阶段。
在放置过程中,您尝试随机添加对象,并使用碰撞检测来决定是否必须再次尝试放置新添加的对象,直到随机位置不会导致碰撞。
在后面的阶段,你可以改变你的碰撞检测处理程序的处理,做任何你喜欢的事情。
要么在不同的阶段替换处理程序,要么通过一些模式变量区分发生了什么。
可能看起来很有趣,也许你可以在不渲染物体的情况下这样做,或者先渲染物体上的白色,然后改变颜色。