Reputation: 145
I am trying to create a demo game just like Doodle Jump and i am stuck in the most silly case. My bouncing ball just misses some platforms (falls through) when checking for collision.
Any ideas on that? Codepen follows for help.
I've tried sorting the platforms in the array (thinking that this was the error), to no avail of course.
Here is my codepen example for showing the case. https://codepen.io/v4vaios/pen/ZEzpozg
checkPlatformCollision(platforms) {
if (goingDown) {
for(let j=0; j<platforms.length; j++) {
let distX = Math.abs(this.x - platforms[j].x-platformWidth/2);
let distY = Math.abs(this.y - platforms[j].y-platformHeight/2);
let dx=distX-platformWidth/2;
let dy=distY-platformHeight;
if (dx*dx + dy*dy <= (this.r*this.r)) {
return true
}
}
}
return false
}
Upvotes: 2
Views: 90
Reputation: 11277
You made several flaws there :
Your collision detector don't works when ball goes UP (no need for check if (goingDown)
), because collision may occur on ball traveling ANY direction.
Second flaw is that you are measuring distance from ball center to rectangle center. When ball will collide with far side of rectangle you will not detect collision. Like this:
dist <= r
is FALSE, so no collision detected
What you need is to calculate circle centers distance to NEAREST point on rectangle, like this:
When ball will reach rectangle, dist <= r will be TRUE.
While fixing these flaws, we get such collision detection function:
checkPlatformCollision(platforms) {
for(let j=0; j<platforms.length; j++) {
let NearestX = Math.max(platforms[j].x, Math.min(this.x, platforms[j].x + platformWidth));
let NearestY = Math.max(platforms[j].y, Math.min(this.y, platforms[j].y + platformHeight));
let dx = Math.abs(this.x - NearestX);
let dy = Math.abs(this.y - NearestY);
if (dx*dx + dy*dy <= (this.r*this.r)) {
return true;
}
}
return false;
}
Upvotes: 1
Reputation: 145
Seems that making the following changes fixed the problem. Now the collision detection works just fine.
checkPlatformCollision(platforms) {
for(let j=0; j<platforms.length; j++) {
if (
(goingDown) &&
(this.x < platforms[j].x + platformWidth) &&
(this.x + this.r > platforms[j].x) &&
(this.y + this.r > platforms[j].y) &&
(this.y + this.r < platforms[j].y + platformHeight)
) {
return true
}
}
return false
}
Upvotes: 0