MOVING TO OBJECT-ORIENTED COLLISION
Congrats! You've made it through a lot of collision-detection code. But these examples are meant as simple demonstrations of how the algorithms work. Combining them into bigger projects probably means moving your code to an object-oriented approach. (For an excellent introduction to object-oriented programming, see Daniel Shiffman's book "Nature Of Code".)
Why? Let's say we have a circle and a bunch of rectangles (like above). We could store separate positions, sizes, and collisions for each, but that would quickly get messy. Instead, a Circle and Rectangle class will give our code a lot more power and flexibility. And, of course, we'll be using the brand new ES6 classes.
Let's start with our Circle class:
{ thisx = _x; thisy = _y; thisr = _r; } { thisx = mouseX; thisy = mouseY; } { ; ; ; }Now that we have the template, let's make an object:
var mouseCircle = 0 0 30;Pretty straightforward. We can also make a basic Rectangle class:
{ thisx = _x; thisy = _y; thisw = _w; thish = _h; thishit = false; } // check for collision with the circle using the // Circle/Rect function we made in the beginning { thishit = ; } // draw the rectangle // if hit, change the fill color { if thishit ; else ; ; ; }Notice we have a variable for the Rectangle called hit. This way we can keep track of whether or not the circle has hit a particular rectangle and change its fill color accordingly. By default, the value is set to false.
We have just one Circle, but we create an Array of Rectangle objects. To run everything, here's what our main draw() loop looks like:
{ ; // go through all rectangles... for var i = 0; i < rectslength; i++ rectsidisplay; // and draw // update circle's position and draw mouseCircle; mouseCircledisplay;}So how do we test if the circle has hit something? Let's create a method (an internal function) of the Rectangle class called checkCollision(). We'll pass the Circle object as an argument, then do a basic Circle/Rectangle collision test.
// check for collision with the circle using the// Circle/Rect function we made in the beginning { thishit = ;}The result of circleRect() sets hit to be true or false, which in turn changes the fill color. Now we just add the test to the draw() loop:
// go through all rectangles...for var i = 0; i < rectslength; i++ rectsi; // check for collision rectsidisplay; // and drawPretty cool! Here's the full code:
// a single Circle object, controlled by the mousevar mouseCircle; // a list of rectanglesvar rects = 8; { var canvas = ; canvasparent"sketch"; // create a new Circle with 30px radius mouseCircle = 0 0 30; // generate rectangles in random locations // but snap to grid! for var i = 0; i < rectslength; i++ var x = * 50; var y = * 50; rectsi = x y 50 50; } { ; // go through all rectangles... for var i = 0; i < rectslength; i++ rectsi; // check for collision rectsidisplay; // and draw // update circle's position and draw mouseCircle; mouseCircledisplay;} // Circle class { thisx = _x; thisy = _y; thisr = _r; } { thisx = mouseX; thisy = mouseY; } { ; ; ; } // Rectangle class { thisx = _x; thisy = _y; thisw = _w; thish = _h; thishit = false; } // check for collision with the circle using the // Circle/Rect function we made in the beginning { thishit = ; } // draw the rectangle // if hit, change the fill color { if thishit ; else ; ; ; } // CIRCLE/RECTANGLE { // temporary variables to set edges for testing var testX = cx; var testY = cy; // which edge is closest? // test left edge if cx < rx testX = rx; else if cx > rx + rw // right edge testX = rx + rw; // top edge if cy < ry testY = ry; else if cy > ry + rh // bottom edge testY = ry + rh; // get distance from closest edges var distance = ; // if the distance is less than the radius, collision! if distance <= radius return true; return false;}You can see another, more complex example of object-oriented collision in the Introduction. It uses a class for circles, rectangles, and lines.