1

Alright, so my simple collision detection algorithm isn't working. It always activates (Unless the player doesn't have any collisions on his x and/or y plains).

Well, here's the code:

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;
                }
            }
        }
    }
}

See any reason on why it's activating when it shouldn't?

2 Answers 2

2

Try this:

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?
}

To answer your question as to why your current logic is not correct, let's focus on one problem. Your logic says basically that there is a collision if:

(YourLeftEdgeIsPastMyLeftEdge AND YourLeftEdgeIsNotPastMyRightEdge) OR
((Something AND Something) AND (Something AND Something))
OR
(Something AND Something)

The middle line is because && has higher precedence than ||, causing the middle two lines of your condition to be clumped together.

Looking that that, we can see that a the collision can succeed by checking only the horizontal placement of the two items, which is clearly a mistake.

The logic I have in my answer is basically that two objects do not overlap if:

  • A. The right edge of one is to the left of the left edge of the other, OR
  • B. The left edge of one is to the right of the right edge of the other, OR
  • C. The bottom edge of one is above the top edge of the other, OR
  • D. The top edge of one is below the bottom edge of the other.

De Morgan's Laws say that !(A || B || C || D) is the same as (!A && !B && !C && !D), and so we can say that two objects do overlap if:

  • A. The right edge of one is to the right of the left edge of the other, AND
  • B. The left edge of one is to the left of the right edge of the other, AND
  • C. The bottom edge of one is below the top edge of the other, AND
  • D. The top edge of one is above the bottom edge of the other.

And this results in the code I supplied:
(x2>this.x) && (x<(this.x+this.width)) && (y2>this.y) && (y<(this.y+this.height))

Sign up to request clarification or add additional context in comments.

Comments

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;
}

So, if you want it to always activate EXCEPT when there's a collision, use !spritecollision.

Source: http://nextgengame.webs.com/fun.htm

EDIT: This is the best answer. It's perfect.

2 Comments

Separate from validating your boolean logic, this is shorter and better: return x2<(x1+w1) && (x2+w2)>x1 && y2<(y1+h1) && (y2+h2)>y1;
No, I only work with type Number. Who needs boolean? This is MY function, and I use it on my site.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.