gpt4 book ai didi

javascript - 我的重力模拟卡住了

转载 作者:行者123 更新时间:2023-11-30 11:27:33 25 4
gpt4 key购买 nike

我正在制作一个重力模拟器来感受基于物理的编码,我在这里提出了一个想法。但是我有一个问题,在弹跳后的某个点之后,粒子(正方形)被卡在弹跳到同一点上。有谁知道为什么吗?

这是 jsfiddle 的链接:https://jsfiddle.net/jjndeokk/6/

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var gravity, objectDensity, force;
gravity = 10.8;

function Object(mass, x, y, w, h, acc, hacc) {
this.m = mass;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.a = acc;
this.ha = hacc;
};
var particle = [];
var rows = [1];
for (let i = 0, len = rows.length; i < len; i++) {
particle.push(new Object(10, i * 30, 10, 20, 20, 0, 0));
};

function draw() {
ctx.clearRect(0, 0, c.width, c.height)
for (let i = 0, len = particle.length; i < len; i++) {
ctx.fillRect(particle[i].x, particle[i].y, particle[i].w, particle[i].h)
particle[i].a += gravity;
particle[i].ha = 3;
particle[i].x += particle[i].ha;
if (particle[i].y + particle[i].h + particle[i].a > c.height) {
particle[i].y = c.height - particle[i].h;
} else {
particle[i].y += particle[i].a;
}
}
}

function update() {
for (let i = 0, len = particle.length; i < len; i++) {
if (particle[i].a >= 0) {
if (particle[i].y + particle[i].h >= c.height) {
particle[i].a *= -1;

}
}
}
draw();
}
setInterval(update, 60);

最佳答案

弹跳卡住的主要原因是您正在对点施加重力,即使它在地面上也是如此。之后,您反转它的速度,它就会飞回空中。

您需要检查它是否在地面上,如果是则不施加重力:

if (isAboveFloor(particle)) {
particle.a += gravity;
}

修复后,您实际上会发现反弹在其初始高度和地面之间来回移动,这是可以预料的 - 这是动量守恒。

为了让反弹更真实,需要引入一个小于1的“恢复系数”:

if (particle.y + particle.h >= c.height) {
particle.a *= -cRest; // cRest is between 0 and 1
}

完成后,您将得到一个非常好的模拟:https://jsfiddle.net/jjndeokk/17/

我还做了以下修改:

  • 使用 .forEach 这样代码就不会完全被 [i]
  • 弄得乱七八糟
  • 使重力和速度计算考虑了时间
  • particle.aparticle.ha 重命名为 particle.vyparticle.vx 因为这些属性正在测量速度,而不是加速度。
  • 将所有计算移到 update() 函数中,这样您就不会在 draw() 函数中进行大部分计算。

var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var gravity, objectDensity, force;
gravity = 240; // pixels / second / second
var cRest = 0.6;

var interval = 60;
var secondsPerInterval = interval / 1000;

function Object(mass, x, y, w, h, vxi, vyi) {
this.m = mass;
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.vx = vxi;
this.vy = vyi;
};
var particles = [];
var rows = [1];
for (let i = 0, len = rows.length; i < len; i++) {
particles.push(new Object(10, i * 30, 10, 20, 20, 40, 0));
};

function draw() {
ctx.clearRect(0, 0, c.width, c.height);
particles.forEach(function(particle) {
ctx.fillRect(particle.x, particle.y, particle.w, particle.h);
})
}

function isAboveFloor(particle) {
return Math.abs(particle.y + particle.h - c.height) > 1;
}

function update() {
particles.forEach(function(particle) {
if (particle.vy < 0 || isAboveFloor(particle)) {
particle.x += particle.vx * secondsPerInterval;
particle.y = Math.min(particle.y + particle.vy * secondsPerInterval, c.height - particle.h);

// if still above floor, accelerate
if(isAboveFloor(particle)){
particle.vy += gravity * secondsPerInterval;
}
}

if (particle.vy >= 0 && particle.y + particle.h >= c.height) {
particle.vy *= -cRest;
}
console.log(particle);
});
draw();
}
setInterval(update, interval);
<canvas id="canvas" height="600" width="800"></canvas>

关于javascript - 我的重力模拟卡住了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47397428/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com