Vaios Anastasiadis
Vaios Anastasiadis

Reputation: 145

Bouncing ball misses some platforms when colliding

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

Answers (2)

Agnius Vasiliauskas
Agnius Vasiliauskas

Reputation: 11277

You made several flaws there :

  1. 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.

  2. 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: enter image description here

dist <= r is FALSE, so no collision detected

What you need is to calculate circle centers distance to NEAREST point on rectangle, like this:

enter image description here

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

Vaios Anastasiadis
Vaios Anastasiadis

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

Related Questions