4

I have a canvas, and I'm using geolocation, google maps and openweathermap to get the weather of where the user is. The weather will be taken and cause the game I'm making to also use that weather...

How can I check if two squares that are spawned onto the canvas overlap? This is the code for the rain, which looks nothing like rain at the moment...

function rectangle(x, y, w, h) {
    var randomx = Math.floor(Math.random() * canvas.width - 50);
    this.x = randomx || x || 0;
    this.y = y || 0;
    this.w = w || 0;
    this.h = h || 0;
    this.expired = false;

    this.draw = function() {
        cx.fillStyle = "blue";
        cx.fillRect(this.x, this.y, this.w, this.h);
    };

    this.update = function() {
        this.y++;
            if (y > canvas.height) {
                this.expired = true;
            }
    };
}

var rectangles = new Array();
function newRect() {
    rectangles.push(new rectangle(window.randomx, window.y, 10, 10));
}
var timing = 0;

function loop() {
    cx.clearRect(0, 0, canvas.width, canvas.height);
    if (timing % 10 === 0) {
        newRect();
    }

    for (var i = 0, l = rectangles.length; i < l; i++) {
        rectangles[i].update();
        rectangles[i].draw();
        if (rectangles[i].expired) {
            rectangles.splice(i, 1);
            i--;
        }
    }
    timing++;
    requestAnimFrame(loop);
}
loop();

My assumption, is that I need to perform a 'hit test' to see if two rectangles in the array are in the same perimeter... I guess where my this.draw and this.update function are I should do something like...

this.hitTest = function () {
    //Maths to check here
};

Then in the forloop do...

rectangles[i].hitTest();

But I'm not sure on the Maths or where to go from there...

Any help would be appreciated, thanks in advance!

  • I went to a hackathon the other week and worked with the canvas element for the first time. I found [this](https://github.com/LawrenceJones/printme/blob/master/app/canvas/Canvas.coffee) to be an effective way of managing a canvas frame, nicely event driven. Also found [this](http://simonsarris.com/blog/510-making-html5-canvas-useful) tutorial to be an incredible help. – Lawrence Jones Dec 30 '13 at 20:27
  • @LawrenceJones, Thank you for both of them, they do like quite interesting. But I forgot to mention that I won't be using any frameworks or external libraries. It has to be done without the use of them –  Dec 30 '13 at 20:36
  • Dan, neither of those solutions make use of any external libraries. Whilst the first link may be surrounded by angular it's not reliant on it. Just pure javascript in the end. – Lawrence Jones Dec 30 '13 at 20:39

1 Answers1

8

You can extend your rectangle object like this:

function rectangle(x, y, w, h) {

    ... existing code here ...

}

rectangle.prototype.intersects = function(rect) {
    return !( rect.x           > (this.x + this.w) || 
             (rect.x + rect.w) <  this.x           || 
              rect.y           > (this.y + this.h) ||
             (rect.y + rect.h) <  this.y);
}

Based on this code by Daniel Vassallo, adopted for your object.

Now simply call the function on the rectangle you want to compare with:

 if ( rectangles[x].intersects(rectangles[y]) ) {
     ... they intersect ...
 }

To check if a new rectangle intersects with an existing you can do:

function isOverlapping(myNewRect, rectangles) {

    for(var i = 0, r; r = rectangles[i]; i++) {
        if (myNewRect.intersect(r)) return true;
    }
    return false;
}
Community
  • 1
  • 1
  • I understand the logic behind this, and understand why it SHOULD work, but for some reason they still overlap? I also tried putting a console.log(); inside the if statement, but it doesn't show anything in the console –  Dec 30 '13 at 22:03
  • @Dan could be I misunderstood your question.. I interpreted it as you want to detect if two rectangles overlap (or intersects)? If you in addition need to prevent this (if they do) you can simply remove the rectangle that overlaps or not draw it. –  Dec 30 '13 at 22:08
  • I want to check if two of the rectangles overlap one another, so if they appear on top of each other, even if it's like 1px over the corner of another. And I know I should just remove it, but I don't know how to check if the rectangle is trying to spawn in a place that has already been taken –  Dec 30 '13 at 22:12
  • @Dan ah, before adding a new rectangle just iterate the array with existing rectangles and use the method on the new rectangle (the one not added yet). Updated answer. –  Dec 30 '13 at 23:57
  • Okay thank you, but there are two errors with this... 1) the for loop throws an error because there are not 3 parameters, 2) break at that point is an illegal statement –  Dec 31 '13 at 13:57
  • @Dan Sorry about that. It was busy yesterday with 1k interruptions.. I've updated the answer. Though, the main focus with the answer is how to detect intersection. If you think that answered the question consider to accept/upvote. –  Dec 31 '13 at 16:30
  • That's no worries! but yes, just took a look at your updated answer and have gotten it working now! thank you very much for the help –  Dec 31 '13 at 23:06