p5.js collision/object interaction. Ball bounce

末鹿安然 提交于 2019-12-24 01:09:53

问题


Following the collision between a ball from an array and an object (rectangle), the ball doesn't seem to have the same bounce affect as it has when it hits the ground.

When coming into contact with the object, it seems to pick up speed and suddenly glitches through and comes to rest on the ground.

Questions:

  1. Why does it seem to want to rest on the ground and not on the object itself?
  2. How can I make the ball have the same bounce affect when coming into contact with the object as it has when coming into contact with the ground?

Code:

    var balls = [];
    var obstacle;

    function setup() {
      createCanvas(400, 400);
      obstacle = new Obstacle();
    }

    function draw() {
      background(75);
      obstacle.display();
      for (var i = 0; i < balls.length; i++) {
        balls[i].display();
        balls[i].update();
        balls[i].edges();
        RectCircleColliding(balls[i], obstacle);
        //console.log(RectCircleColliding(balls[i], obstacle));
      }
    }

    function mousePressed() {
      balls.push(new Ball(mouseX, mouseY));
    }

    function Ball(x, y) {
      this.x = x;
      this.y = y;
      this.r = 15;
      this.gravity = 0.5;
      this.velocity = 0;
      this.display = function() {
        fill(255, 0, 100);
        stroke(255);
        ellipse(this.x, this.y, this.r * 2);
      }
      this.update = function() {
        this.velocity += this.gravity;
        this.y += this.velocity;
      }
      this.edges = function() {
        if (this.y >= height - this.r) {
          this.y = height - this.r;
          this.velocity = this.velocity * -1;
          this.gravity = this.gravity * 1.1;
        }
      }
    }

    function Obstacle() {
      this.x = width - width;
      this.y = height / 2;
      this.w = 200;
      this.h = 25;

      this.display = function() {
        fill(0);
        stroke(255);
        rect(this.x, this.y, this.w, this.h);
      }
    }

    function RectCircleColliding(Ball, Obstacle) {
      // define obstacle borders
      var oRight = Obstacle.x + Obstacle.w;
      var oLeft = Obstacle.x;
      var oTop = Obstacle.y;
      var oBottom = Obstacle.y + Obstacle.h;

      //compare ball's position (acounting for radius) with the obstacle's border
      if (Ball.x + Ball.r > oLeft) {
        if (Ball.x - Ball.r < oRight) {
          if (Ball.y + Ball.r > oTop) {
            if (Ball.y - Ball.r < oBottom) {
              Ball.y = Obstacle.y - Ball.r * 2;
              Ball.velocity = Ball.velocity * -1;
              Ball.gravity = Ball.gravity * 1.1;
              Ball.velocity += Ball.gravity;
              Ball.y += Ball.velocity;

              return (true);
            }
          }
        }
      }
      return false;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>

回答1:


The main issue with this question's code is that we need to check for collisions and only allow updates when the ball is not colliding. Another issue was that when collisions occur we must cap the gravity to prevent the ball from plunging all the way to the ground.

Here is the corrected code:

var balls = [];
var obstacle;

function setup() {
  createCanvas(400, 400);
  obstacle = new Obstacle();
}

function draw() {
  background(75);
  obstacle.display();
  for (var i = 0; i < balls.length; i++) {
    balls[i].display();
	if (!RectCircleColliding(balls[i], obstacle)){
    balls[i].update();
    balls[i].edges();
	}
    
    //console.log(RectCircleColliding(balls[i], obstacle));
  }
}

function mousePressed() {
  balls.push(new Ball(mouseX, mouseY));
}

function Ball(x, y) {
  this.x = x;
  this.y = y;
  this.r = 15;
  this.gravity = 0.5;
  this.velocity = 0;
  this.display = function() {
    fill(255, 0, 100);
    stroke(255);
    ellipse(this.x, this.y, this.r * 2);
  }
  this.update = function() {
    this.velocity += this.gravity;
    this.y += this.velocity;
  }
  this.edges = function() {
    if (this.y >= height - this.r) {
      this.y = height - this.r;
      this.velocity = this.velocity * -1;
      this.gravity = this.gravity * 1.1;
    }
  }
}

function Obstacle() {
  this.x = width - width;
  this.y = height / 2;
  this.w = 200;
  this.h = 25;

  this.display = function() {
    fill(0);
    stroke(255);
    rect(this.x, this.y, this.w, this.h);
  }
}

function RectCircleColliding(Ball, Obstacle) {
  // define obstacle borders
  var oRight = Obstacle.x + Obstacle.w;
  var oLeft = Obstacle.x;
  var oTop = Obstacle.y;
  var oBottom = Obstacle.y + Obstacle.h;

  //compare ball's position (acounting for radius) with the obstacle's border
  if (Ball.x + Ball.r > oLeft) {
    if (Ball.x - Ball.r < oRight) {
      if (Ball.y + Ball.r > oTop) {
        if (Ball.y - Ball.r < oBottom) {
         let oldY = Ball.y;
         Ball.y = oTop - Ball.r;
         Ball.velocity = Ball.velocity * -1;
         if (Ball.gravity < 2.0){
          Ball.gravity = Ball.gravity * 1.1;  
         } else {
           Ball.velocity = 0;
           Ball.y = oldY;
         }   
         return (true);
        } 
      }
    }
  }
  return false;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>


来源:https://stackoverflow.com/questions/49924036/p5-js-collision-object-interaction-ball-bounce

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!