Collision detection is a fundamental concept in computer graphics and game development. It involves determining when two or more objects in a virtual space intersect or come into contact with each other. In this blog, we'll explore how to implement collision detection for rectangles and circles using HTML Canvas. We'll break down the principles, provide sample code, and discuss practical applications of these concepts.
Collision detection refers to the process of identifying when two objects intersect or overlap in a given space. This is crucial for a wide range of applications, including:
In this blog, we'll focus on detecting collisions between a rectangle and a circle and how to handle edge collisions with the canvas boundaries.
Let's start by implementing a class for a rectangle. The Rect
class will manage the rectangle's position, dimensions, color, and velocity.
class Rect {
constructor(x, y, width, height, color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
this.velocity = {
x: random(-3, 3),
y: random(-3, 3)
};
}
}
constructor(x, y, width, height, color)
: Initializes the rectangle's position (x
, y
), dimensions (width
, height
), color, and velocity. The velocity is assigned a random value to create movement.draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
draw()
: Draws the rectangle on the canvas using its color, position, and dimensions.update() {
this.x += this.velocity.x;
this.y += this.velocity.y;
// Check for collision with canvas edges
if (this.x + this.width > canvas.width || this.x < 0) {
this.velocity.x = -this.velocity.x;
}
if (this.y + this.height > canvas.height || this.y < 0) {
this.velocity.y = -this.velocity.y;
}
this.draw();
}
update()
: Updates the rectangle's position based on its velocity and checks for collisions with the canvas edges. If it hits an edge, the velocity is reversed to simulate a bounce.getBounds() {
return {
left: this.x,
right: this.x + this.width,
top: this.y,
bottom: this.y + this.height
};
}
getBounds()
: Returns the boundary coordinates of the rectangle, which are useful for collision detection with other shapes.Next, we'll implement a class for a circle. The Circle
class will manage the circle's position, radius, color, and velocity.
class Circle {
constructor(x, y, radius, color) {
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = {
x: random(-3, 3),
y: random(-3, 3)
};
}
}
constructor(x, y, radius, color)
: Initializes the circle's position (x
, y
), radius, color, and velocity. Like the rectangle, the velocity is assigned a random value.draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.closePath();
}
draw()
: Draws the circle on the canvas using its color, position, and radius.update() {
this.x += this.velocity.x;
this.y += this.velocity.y;
// Check for collision with canvas edges
if (this.x + this.radius > canvas.width || this.x - this.radius < 0) {
this.velocity.x = -this.velocity.x;
}
if (this.y + this.radius > canvas.height || this.y - this.radius < 0) {
this.velocity.y = -this.velocity.y;
}
this.draw();
}
update()
: Updates the circle's position based on its velocity and checks for collisions with the canvas edges. The velocity is reversed if it hits an edge to create a bounce effect.getBounds() {
return {
left: this.x - this.radius,
right: this.x + this.radius,
top: this.y - this.radius,
bottom: this.y + this.radius
};
}
getBounds()
: Returns the boundary coordinates of the circle, which are crucial for detecting collisions with other shapes.To detect collisions between a rectangle and a circle, we need to determine if the circle's position intersects with the rectangle's bounds.
function checkCollision(rect, circle) {
const rectBounds = rect.getBounds();
const circleBounds = circle.getBounds();
// Closest point on the rectangle to the circle
const closestX = Math.max(rectBounds.left, Math.min(circle.x, rectBounds.right));
const closestY = Math.max(rectBounds.top, Math.min(circle.y, rectBounds.bottom));
// Distance from closest point to the circle center
const distanceX = circle.x - closestX;
const distanceY = circle.y - closestY;
return Math.sqrt(distanceX ** 2 + distanceY ** 2) < circle.radius;
}
checkCollision(rect, circle)
: This function calculates the closest point on the rectangle to the circle. It then measures the distance between this point and the circle's center. If this distance is less than the circle's radius, a collision is detected.Understanding and implementing collision detection is crucial in various domains, including:
By mastering these concepts, developers can create more interactive and dynamic experiences in their applications.
Feel free to use and adapt this code for your own projects, and let me know if you have any questions or feedback!