需要帮助简单的碰撞检测算法

时间:2011-01-23 19:15:08

标签: javascript html html5 canvas

好吧,所以我的简单碰撞检测算法不起作用。它总是激活(除非玩家在他的x和/或y平原上没有任何碰撞)。

嗯,这是代码:

collisionCheck: function(bArray){
    for(var i = 0; i < bArray.length; i++){
        for(var j = 0; j < bArray[i].length; j++){
            if(bArray[i][j].getType() != 0){
                if((bArray[i][j].getX() > this.x && bArray[i][j].getX() < this.x + this.width) ||
                    (bArray[i][j].getX() + blockSize > this.x && bArray[i][j].getX() + blockSize < this.x + this.width) &&
                    (bArray[i][j].getY() > this.y && bArray[i][j].getY() < this.y + this.height) || 
                    (bArray[i][j].getY() + blockSize > this.y && bArray[i][j].getY() + blockSize < this.y + this.height)){
                    this.x = 0;
                }
            }
        }
    }
}

看到它不应该激活的原因是什么原因?

2 个答案:

答案 0 :(得分:2)

试试这个:

collisionCheck: function(bArray){
  for(var i=0,len=bArray.length; i<len; ++i){
    for(var j=0,len2=bArray[i].length; j<len2; ++j){
      if(!bArray[i][j].getType()) continue;
      var x = bArray[i][j].getX(), y = bArray[i][j].getY();
      var x2 = x+blockSize, y2 = y+blockSize;
      var overlapping = (x2>this.x) && (x<(this.x+this.width)) && (y2>this.y) && (y<(this.y+this.height));
      if (overlapping) this.x = 0; // I don't know why you'd do this, but it's what you have
    }
  }
  // Should this function return anything?
}

要回答关于为什么当前逻辑不正确的问题,让我们关注一个问题。你的逻辑基本上说如果发生了碰撞:

  

(YourLeftEdgeIsPastMyLeftEdge和YourLeftEdgeIsNotPastMyRightEdge)   OR
  ((某事和某事)和(某事和某事))
  OR
  (某事和某事)

中间一行是因为&&higher precedence而不是||,导致条件的中间两行聚集在一起。

看着这一点,我们可以看到碰撞只能通过检查两个项目的水平放置来成功,这显然是个错误。

我在答案中的逻辑基本上是两个对象 重叠,如果:

  • 甲。一个的右边缘位于另一个的左边缘的左边,或者
  • B中。一个的左边缘位于另一个的右边缘右侧,或者
  • ℃。一个的底边缘位于另一个的顶边缘上方,或者
  • d。一个的上边缘低于另一个的下边缘。

De Morgan's Laws!(A || B || C || D)(!A && !B && !C && !D)相同,因此我们可以说两个对象 重叠:

  • 甲。一个的右边缘是另一个的左边缘的右边,AND
  • B中。一个的左边缘是另一个的右边缘的,AND
  • ℃。一个的下边缘低于另一个的上边缘,AND
  • d。一个的上边缘高于另一个的下边缘。

这导致我提供的代码:
(x2>this.x) && (x<(this.x+this.width)) && (y2>this.y) && (y<(this.y+this.height))

答案 1 :(得分:0)

function spritecollision(x1,y1,w1,h1,x2,y2,w2,h2){
    if(x2<(x1+w1)&&(x2+w2)>x1&&y2<(y1+h1)&&(y2+h2)>y1)return 1;
}

因此,如果您希望在发生碰撞时始终激活EXCEPT,请使用!spritecollision

来源:http://nextgengame.webs.com/fun.htm

编辑:这是最好的答案。这很完美。