p5.j​​s碰撞/对象交互。球反弹

时间:2018-04-19 14:49:30

标签: javascript processing collision-detection interaction p5.js

在阵列中的球与物体(矩形)发生碰撞之后,球似乎没有像撞击地面时那样具有相同的弹跳效果。

当与物体接触时,它似乎加快速度并突然出现故障并停留在地面上。

问题:

  1. 为什么它似乎想要在地面而不是在物体本身上休息?
  2. 当接触物体与接触地面时,如何使球具有相同的弹跳效果?
  3. 代码:

    
    
        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;
        }
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:1)

该问题代码的主要问题是我们需要检查碰撞并仅在球不碰撞时才允许更新。另一个问题是,在发生碰撞时,我们必须限制重力,以防止球完全跌落到地面。

这是更正的代码:

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>