p5.collide2D
p5.collide2D copied to clipboard
Can you guys add some functionality?
don't be wrong, it's a pretty helpful plugin for my games. but, it's only detect the collision which only a bool, I have to smuggle some code so I know which direction the collision came in a rect to rect and circle to circle. so then I can use it on my platformer game. Can you guys add that?
You can definitely do this. Here's an example GPT4 provided for circle2rect collision. Circle2circle should be easier.
In this example collideRectCircle()
is the exact same version as provided by the p5.collide2D library.
function setup() {
createCanvas(400, 400);
noCursor()
}
function draw() {
background(220);
if (collideRectCircle(mouseX, mouseY, 50, 50, 100, 100, 100)) {
fill("red");
} else {
fill("white");
}
rect(mouseX, mouseY, 50, 50);
circle(100, 100, 100);
let pts = collisionPointsRectCircle(mouseX, mouseY, 50, 50, 100, 100, 100);
if (pts) {
for (let pt of pts) {
fill('yellow')
circle(pt.x, pt.y, 5);
}
}
}
function collideRectCircle(rx, ry, rw, rh, cx, cy, diameter) {
//2d
// temporary variables to set edges for testing
var testX = cx;
var testY = cy;
// which edge is closest?
if (cx < rx) {
testX = rx; // left edge
} else if (cx > rx + rw) {
testX = rx + rw;
} // right edge
if (cy < ry) {
testY = ry; // top edge
} else if (cy > ry + rh) {
testY = ry + rh;
} // bottom edge
// // get distance from closest edges
var distance = this.dist(cx, cy, testX, testY);
// if the distance is less than the radius, collision!
if (distance <= diameter / 2) {
return true;
}
return false;
}
function collisionPointsRectCircle(rx, ry, rw, rh, cx, cy, diameter) {
let points = [];
let radius = diameter / 2;
let rectPoints = [
{ x: rx, y: ry },
{ x: rx + rw, y: ry },
{ x: rx, y: ry + rh },
{ x: rx + rw, y: ry + rh },
];
// Check each corner of the rectangle
for (let p of rectPoints) {
if (dist(p.x, p.y, cx, cy) <= radius) {
points.push(p);
}
}
// Check middle points of each rectangle side
let midPoints = [
{ x: rx + rw / 2, y: ry },
{ x: rx, y: ry + rh / 2 },
{ x: rx + rw / 2, y: ry + rh },
{ x: rx + rw, y: ry + rh / 2 },
];
for (let p of midPoints) {
let angle = Math.atan2(p.y - cy, p.x - cx);
let circlePoint = {
x: cx + radius * Math.cos(angle),
y: cy + radius * Math.sin(angle),
};
if (
circlePoint.x >= rx &&
circlePoint.x <= rx + rw &&
circlePoint.y >= ry &&
circlePoint.y <= ry + rh
) {
points.push(circlePoint);
}
}
// Removing duplicate points
points = points.filter(
(point, index, self) =>
index === self.findIndex((t) => t.x === point.x && t.y === point.y)
);
return points;
}
Here's circle2circle as provided by GPT4:
function setup() {
createCanvas(400, 400);
}
function draw() {
background(240);
let circle1 = { x: mouseX, y: mouseY, r: 40 };
let circle2 = { x: 200, y: 200, r: 30 };
let points = circleIntersection(circle1, circle2);
fill("white");
drawCircle(circle1);
drawCircle(circle2);
if (points) {
drawPoints(points);
}
}
function drawCircle(circle) {
ellipse(circle.x, circle.y, circle.r * 2);
}
function drawPoints(points) {
for (let p of points) {
fill(255, 0, 0);
ellipse(p.x, p.y, 10, 10);
}
}
function circleIntersection(c1, c2) {
let d = dist(c1.x, c1.y, c2.x, c2.y);
if (d > c1.r + c2.r || d < abs(c1.r - c2.r) || (d === 0 && c1.r === c2.r)) {
return null; // No intersection
}
let a = (c1.r * c1.r - c2.r * c2.r + d * d) / (2 * d);
let h = sqrt(c1.r * c1.r - a * a);
let p2 = {
x: c1.x + (a * (c2.x - c1.x)) / d,
y: c1.y + (a * (c2.y - c1.y)) / d,
};
return [
{
x: p2.x + (h * (c2.y - c1.y)) / d,
y: p2.y - (h * (c2.x - c1.x)) / d,
},
{
x: p2.x - (h * (c2.y - c1.y)) / d,
y: p2.y + (h * (c2.x - c1.x)) / d,
},
];
}