Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将时间增量和速度纳入速度/摩擦运动_Javascript_Animation_Math_Time_Html5 Canvas - Fatal编程技术网

Javascript 将时间增量和速度纳入速度/摩擦运动

Javascript 将时间增量和速度纳入速度/摩擦运动,javascript,animation,math,time,html5-canvas,Javascript,Animation,Math,Time,Html5 Canvas,我正在简单的游戏中尝试运动力学,我发现了一篇非常不错的文章,其中有一个例子,说明了如何通过使用速度和摩擦(非常流行的方法)使其“逼真”。因此,对象开始缓慢,加速到上限,一旦释放关键点,它开始减速,直到0 关键部分是增加“油门”: 利用油门来增加摩擦限制的速度 var friction = 0.97; function updatePosition(obj) { //update velocity obj.vx += obj.ax; obj.vy += obj.ay;

我正在简单的游戏中尝试运动力学,我发现了一篇非常不错的文章,其中有一个例子,说明了如何通过使用速度和摩擦(非常流行的方法)使其“逼真”。因此,对象开始缓慢,加速到上限,一旦释放关键点,它开始减速,直到0

关键部分是增加“油门”:

利用油门来增加摩擦限制的速度

var friction = 0.97;
function updatePosition(obj) {
    //update velocity
    obj.vx += obj.ax;
    obj.vy += obj.ay;

    //apply friction
    obj.vx *= friction;
    obj.vy *= friction;

    //update position
    obj.x += obj.vx;
    obj.y += obj.vy;
}
虽然它看起来很漂亮,感觉也不错,但它打破了我的逻辑,即基于时间的移动。它是强制性的,因此玩家可以看到每秒的速度,因为它允许进行计划升级,计划旅行和燃料使用

因此,当前的实现如下所示:

this.now = undefined;
this.delta = undefined;
this.then = Date.now();

this.setMoveDelta = function() {
  this.now = Date.now();
  this.delta = (this.now - this.then) / 1000;
  this.then = this.now;
};

this.speed = 100; // 100 pixels per second
this.move = function() {
    this.setMoveDelta();
    var partialDistance = this.speed * this.delta;
    this.x += Math.cos(this.rad) * partialDistance;
    this.y += Math.sin(this.rad) * partialDistance;
}
现在,当您运行附带的演示时,可以注意到由于摩擦盖,存在某种“最大”速度。问题是这个上限是否可以设置为
this.speed*this.delta
?或者使用其他方法使船舶以最大速度移动,并声明参数(例如每秒100像素)

其想法是保持加速和减速不变,但一旦船舶达到最大速度,它将是声明的速度(并向用户显示)。然后,该速度用于计算从A点行驶到B点所需的时间以及将使用的燃油量。现在感觉很随意

var canvas=document.createElement('canvas'),
ctx=canvas.getContext('2d'),
w=400,
h=400;
画布宽度=w;
canvas.height=h;
document.body.appendChild(画布);
宇宙飞船={
x:w/2,y:h/2,
vx:0,vy:0,
ax:0,ay:0,
r:0,
绘图:函数(){
ctx.save();
ctx.translate(this.x,this.y);
ctx.旋转(此.r);
ctx.fillStyle='白色';
ctx.fillRect(-10,-5,20,10);
ctx.restore();
}
};
var摩擦=0.97;
函数更新位置(obj){
//更新速度
obj.vx+=obj.ax;
obj.vy+=obj.ay;
应用摩擦(obj);
//更新位置
obj.x+=obj.vx;
对象y+=对象vy;
}
//用户交互
var键=[];
文档.添加的事件列表器('keydown',函数(e){
键[e.which]=true;
});
文件。添加的文件列表器(“键控”,功能(e){
键[e.which]=假;
});
函数应用摩擦(obj){
obj.vx*=摩擦;
obj.vy*=摩擦力;
}
(函数animloop(){
requestAnimationFrame(动画循环、画布);
ctx.fillStyle='#000';
ctx.fillRect(0,0,w,h);
//轮换
if(键[37])宇宙飞船.r-=0.05;
if(键[39])宇宙飞船r+=0.05;
//推力
如果(键[38]){
spaceship.ax=数学cos(spaceship.r)*0.05;
spaceship.ay=数学sin(spaceship.r)*0.05;
}否则{
spaceship.ax=spaceship.ay=0;
}
更新位置(宇宙飞船);
太空船;
})();现在速度是(obj.vx^2+obj.vy^2)/this.delta的根,最大速度是0.05/(1-0.97)/this.delta。第一次是vx和vy每次都在移动增量。后者,因为速度增加0.05与速度降低*(1-0.97)相平衡

答案是速度上限可以通过调整加速度常数0.05或摩擦常数0.97来设置。让我们使用加速一:


加速度常数=max_speed*this.delta*(1-0.97)

看,你的方程式中缺少了
dt
时间步长(从上次迭代或计时器间隔经过的时间)…这就是为什么我问这个问题,希望得到“如何”合并它的帮助,我也不认为
dt
是delta,如果没有速度,我就能达到我所需要的。在链接的答案中,既有
speed
又有
dt
。。。向量形式的积分为:
vel+=acc*dt;pos+=vel*dtacc
[m/s^2]
中的加速度,
vel
[m/s]
中的速度,
pos
[m]
中的位置。。。
dt
[s]
中的标量时间步长。。。。因此,您可以使用驱动力(
acc=F/m
)、重力、推进器等设置
acc
。。。然后计算剩下的。。。。你也可以根据环境(气体、液体)添加摩擦
F=k*| vel | ^2
F=k*| vel | ^3
,有没有可能在所有这些都准备就绪的情况下以答案的形式进行演示,(我是一个非常初学者,在所有这些计算中都迷失了方向),提前感谢你的努力;)只要记住,一定有一个“最高速度”的地方,是在马克斯实现的,像这样:?你只需在某个计时器中调用
ball\u update
,然后重新启动屏幕…我用使用建议公式的新演示更新了我的答案,播放演示,然后打开整页并开始移动(仅向前),你会看到即使你的速度应该限制在每秒100px,另一个物体移动得更快,最终会跑得比你快,你知道为什么吗?你知道怎么解决吗?对不起,我的答案应该是加速度=最大速度*这个.delta*(1/0.97-1),当你这样做时,在“//更新速度”之后应用摩擦力。如果将applyFriction()放在“//update velocity”之前,我的答案应该是正确的。差别不大,但运行代码段时我也能看到。这是完美的解释!而且效果也很好,谢谢;)
this.now = undefined;
this.delta = undefined;
this.then = Date.now();

this.setMoveDelta = function() {
  this.now = Date.now();
  this.delta = (this.now - this.then) / 1000;
  this.then = this.now;
};

this.speed = 100; // 100 pixels per second
this.move = function() {
    this.setMoveDelta();
    var partialDistance = this.speed * this.delta;
    this.x += Math.cos(this.rad) * partialDistance;
    this.y += Math.sin(this.rad) * partialDistance;
}