如何模拟JavaScript中的反弹?

时间:2016-01-17 07:45:00

标签: javascript canvas physics

我试图让一个矩形随着重力下降,当它碰到我的画布底部时反弹,并且在几次弹跳后停止。

使用下面的代码,我的矩形将在击中画布底部后以额外的力量启动。在将加速度设置为零之后,我确定我的等式的速度部分有问题。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');

// System settings
var restitution = -0.7;
var a = -32/Math.pow(1000,2); // acceleration

var myRectangle = {};

var draw = {
    rectangle: function (x, y, width, height) {
        context.beginPath();
        context.rect(x, y, height, width);
        context.fillStyle = '#8ED6FF';
        context.fill();
        context.lineWidth = 5;
        context.strokeStyle = 'black';
        context.stroke();
    }
};

function init() {
    myRectangle = {
        width   : 100,
        height  : 100,
        p_0     : {x:canvas.width/2, y:canvas.height/2},
        p       : {x:canvas.width/2, y:canvas.height/2},
        v_0     : {x:0, y:0},
        v       : {x:0, y:0},
        t_0     : (new Date()).getTime(),
        t       : 0
    };
    animate();
}

function animate() {

    // Bounce on the bottom
    if (    (myRectangle.p.y <= myRectangle.height)
        &&  (myRectangle.v.y < 0)){

        // Create new initial conditions on bounce
        myRectangle.p.y = myRectangle.height;
        myRectangle.p_0 = myRectangle.p;
        myRectangle.v_0.y = restitution * myRectangle.v.y;
        myRectangle.t_0 = (new Date()).getTime();
    }

    // Update rectangle time and position
    myRectangle.t = ((new Date()).getTime() - myRectangle.t_0);
    myRectangle.v.y = a*myRectangle.t + myRectangle.v_0.y;
    myRectangle.p.y = a*Math.pow(myRectangle.t,2)/2 + myRectangle.v_0.y * myRectangle.t + myRectangle.p_0.y;

    context.clearRect(0, 0, canvas.width, canvas.height);
    draw.rectangle(myRectangle.p.x, canvas.height-myRectangle.p.y, myRectangle.width, myRectangle.height);

    window.requestAnimationFrame(animate);
}

1 个答案:

答案 0 :(得分:0)

事实证明,这个等式的初始位置部分实际上是一个错误。我不能简单地将对象设置为等于另一个对象,而是必须单独复制其属性。解决方案如下:

// Bounce on the bottom
    if (    (myRectangle.p.y <= myRectangle.height)
        &&  (myRectangle.v.y < 0)){
        // Create new initial conditions on bounce
        myRectangle.p.y = myRectangle.height;

        // THIS LINE WAS INCORRECT
        myRectangle.p_0.y = myRectangle.p.y;

        myRectangle.v_0.y = restitution * myRectangle.v.y;
        myRectangle.t_0 = (new Date()).getTime();
    }