JavaScript对象定位碰撞逻辑

时间:2014-05-14 19:14:29

标签: javascript

@Pointy:

如下所述,size变量按百分比调整大小。因此,此数字可以具有例如1或1.5或2等的值。默认圆直径为100像素,并且显示的圆的实际直径为size*100。检查碰撞时我使用size*120,因为我想留一些额外的空间。

据我所知,CSS lefttop属性分别根据左边界和上边界定位对象。因此,如果我想检查对象右侧的碰撞,我必须采用左边界并添加圆的直径(由size*100给出)。当检查左侧的碰撞时,我采用左边界并减去size*(1.2-1)*100,因为当我从左边界开始时,我不需要考虑圆的直径。同样的事情适用于y轴。

我希望这是可以理解的,谢谢你帮助我。

原帖:

我的屏幕上有两个圆圈,一个粉红色圆圈和一个紫色圆圈。这些圆(x,y)的位置是随机确定的。最初,页面上只有紫色圆圈。一秒钟后,将出现粉色圆圈。我想检查这两个圆圈是否重叠,如果是,重新定位粉红色圆圈。

我的代码:

   if(document.getElementById("purple").style.left+(size*120) > x 
      && document.getElementById("purple").style.left-(size*20) < x)
   {
        if(x + 200 <= rightBound) {
            x = x+200;
        }
        else {
            x = x-200;
        }
    }
    else if(document.getElementById("purple").style.top+(size*120) > y
            && document.getElementById("purple").style.top-(size*20) < y)
    {
        if(y+200 <= bottomBound) {
            y = y+200;
        }
        else {
            y = y-200;
        }
    }
    document.getElementById("pink").style.left = x+"px";
    document.getElementById("pink").style.top = y+"px";

size变量按百分比修改圆圈大小。默认圆圈大小为100像素,但在我的代码中,我指定120像素以留出一些额外的空间。

rightBoundbottomBound变量决定了圆圈必须随机定位的界限。我的代码检查是否将圆圈向右移动200像素,或向下移动200像素仍将圆圈定位在边界内。如果是这样,则完成此操作,否则圆圈将向左移动200像素。

顺便说一下,如果不清楚xy是粉红色圆圈位置的随机生成值。

但是,使用此代码,我仍然遇到粉红色和紫色圆圈重叠的情况。我想知道我的逻辑问题是什么,就像在我的解释和思考中我觉得一切都应该正常工作。

2 个答案:

答案 0 :(得分:2)

为什么不继续尝试新的粉色圆圈直到你得到一个正确的?毕竟随机数很便宜: http://jsfiddle.net/HVX7d/

while(distance(purple, pink) < 120) {    
  pink = {
    x: int_rand(100, 500),
    y: int_rand(100, 500)
  };  
}

使用循环来保持粉红色的新位置,直到你确定没有碰撞,使用毕达哥拉斯来计算圆圈的距离。

原始答案(错误地认为100是半径): 问题是您在边界逻辑中指定了120,但在检测到时只将圆移动了200。这意味着圈子最初不会重叠,但当你移动它们只有200时,你就会创建一个以前不存在的重叠。

将您的实例200更改为240,您不应再看到任何问题。

例如:你有200,200的紫色和310,200的粉红色。这足以触发你的边界逻辑,因为310 - 200只有110,所以你选择移动粉红色。我们假设您将其向上移动,因为它靠近底部边界,所以现在它处于110,200并且您已经创建了重叠。

答案 1 :(得分:0)

我认为这应该做你需要的:

function reposition_check(x, y, rightBound, bottomBound, size, elem) {
    var c1_size = 120 * size;
    var c2_size = 120 * size;

    var c1_x = parseInt(elem.style.left.replace("px", "")) + (c1_size / 2); //center the purple x coordinate
    var c1_y = parseInt(elem.style.top.replace("px", "")) + (c1_size / 2); //center the purple y coordinate

    var c2_x = x + (c2_size / 2); //center the pink x coordinate
    var c2_y = y + (c2_size / 2); //center the pink y coordinate

    var d_x = c1_x - c2_x; //distance on the x plane
    var d_y = c1_y - c2_y; //distance on the y plane

    if (Math.sqrt((d_x * d_x) + (d_y * d_y)) < (c1_size / 2) + (c2_size / 2)) { //Pythagorean theorum to determine if overlapping
        console.log("is overlapping");
        if (Math.abs(d_x) < (c1_size / 2) + (c2_size / 2)) { //if true, the overlap is on the x plane
            //if(x + (c2_size) + 200 <= rightBound && d_x > 0) {
            if(d_x > 0) {
                x = (x + 200 <= rightBound) ? x + 200 : (x - 200 - d_x);
            }else{
                x = (x + 200 <= rightBound) ? x - d_x + 200 : (x - 200);
            }
            return {x: x, y: y};
        }

        if (Math.abs(d_y) < (c1_size / 2) + (c2_size / 2)) { //if true, the overlap is on the y plane
            if(d_y > 0) {
                y = (y + 200 <= bottomBound) ? y + 200 : (y - 200 - d_y);
            }else{
                y = (y + 200 <= bottomBound) ? y - d_y + 200 : (y - 200);
            }
            return {x: x, y: y};
        }

    }
    return {x: x, y: y};
}

//Here's how you would use it:

var purple = document.getElementById("purple");
var values = reposition_check(111, 1, 1000, 800, 1, purple); //x, y, rightBound, bottomBound, size, element

document.getElementById("pink").style.left = values.x + "px";
document.getElementById("pink").style.top = values.y + "px";