停止在重力作用下弹跳的球消失

Stop bouncing ball under gravity from disappearing

我想模拟一个弹跳的球,以后再创造更多,让它们弹起来。这是我的代码(使用 p5.js,javascript 的处理库)

var xpos = 200;
var ypos = 450;
var vy = 0;
var gravity = 0.6;
var bounce = -1.00;
var diameter = 30;

function setup() {
    var myCanvas = createCanvas(windowWidth, windowHeight);

    stroke(255);
    noFill();
}

function draw() {
    background(0);

  ellipse(xpos, ypos, diameter, diameter);

  vy += gravity;
  ypos += vy;

  if(ypos > (windowHeight - diameter/2)) {
    vy *= bounce;
  }

}

看起来好像工作正常,但是当反弹变得非常小时,它开始出现故障并消失,here's a codepen。我不知道如何让它停止并滚动或其他东西(如果没有 x 属性 显然不会滚动,但在弹跳停止后停止移动)

感谢任何帮助,谢谢。

通过进行两项调整,我能够更接近地模拟弹跳球:

  1. 如果球接触 'floor' 并且没有移动,请不要施加重力
  2. 衰减降低 每次反弹期间的速度大小
  3. 一旦幅度足够小,将速度设置为 0

更新弹跳:

// Attenuate velocity by making the magnitude of this value < 1
var bounce = -0.9;

// Give initial vy
var vy = 0.1;

并确保我们只在球为 "in the air" 时添加重力(防止我们的球来自 "sinking beneath the ground"):

function draw() {
    background(0);

    ellipse(xpos, ypos, diameter, diameter);

    var floor = windowHeight - diameter/2;
    var inAir = ypos <= floor;
    var moving = Math.abs(vy) > 0.01;

    if (inAir && moving) {
        vy += gravity;
    }

    ypos += vy;

    if(!inAir && vy > 0) {
        vy *= bounce;

        if (!moving) {
            vy = 0;
        }
    }
}

您想先应用加速度,然后进行碰撞测试,然后调整碰撞位置。

如果您想要恢复原状,请在每次碰撞后将其应用于 vy,例如

编辑:还使用检查来查看对象是否应该 "resting" 有帮助

var xpos = 200;
var ypos = 0;
var vy = 0;
var gravity = 10;
var bounce = 0.9;  // typically represented as a positive normalized value
var diameter = 30;
var sleepTolerance = gravity;  // this will provide a solid result

// KA variables
var windowHeight = height;
var windowWidth = width;

frameRate(30);
var draw = function() {
    background(0);

    ellipse(xpos, ypos, diameter, diameter);

    var asleep = false;

    if(!asleep){
        vy += gravity;
        ypos += vy;
    }

    var heightAboveGround = ypos - (windowHeight - diameter/2);
    if(heightAboveGround > 0) { // remember y is inverted
        // position adjusted for reflection after collision
        // including restitution (resulting from the bounce)
        ypos -= bounce * heightAboveGround;

        // apply restitution to subsequent velocity
        vy *= -bounce;

        if (heightAboveGround <= sleepTolerance && abs(vy) <= sleepTolerance){
            asleep = true;
            ypos = windowHeight - diameter/2;
        }
    }
};