Skip to JSFiddle
我正在创建这些与鼠标交互的有趣脚本之一。我决定想要一个物体慢慢地跟随鼠标。我制作了这样的对象,它具有以下属性:
speed - current speed of the object
speed change ratio - derivative of the speed function: "How's the speed changing now?"
direction - radian angle upon which the object is moving
direction change - same as for speed, this is used to change the direction
变化率是随机生成的,并添加到速度
和方向
:
//Do not do it allways
if(rand(0,5)>3) {
speed+=speed_change;
direction+=dir_change;
//Only sometimes, so that they actually have some time to take effect
if(rand(0,10)<=3) {
dir_change = rand(-1,1);
speed_change = rand(-2,2)/10;
}
}
使速度变化效果更加平滑的唯一方法是添加比率的比率和比率的比率的比率等等......我想不出其他任何东西。
现在就说到这里了。您已经看到,默认情况下的移动是随机的,这是有意的。如果我禁用随机比率并应用此代码,它会跟随鼠标位置:
var my_angle = Math.atan2(flyPos[1]-flyTo[1], flyPos[0]-flyTo[0])-Math.PI;
direction = my_angle;
//Inital speed is random, so here is some fix for it (the class also has soft-cap for speed, so it won't reach high numbers)
if(speed<0)
speed_change = 0.1;
这是我谈到的简单的速度软上限,以防万一您想查看它:
if(Math.abs(speed)>6) {
//Dividing speed by |speed| leads +1 or -1, but it's pretty unefective
speed_change = (-1)*(speed/Math.abs(speed));
}
现在,我想要的是改变dir_change
而不是direction
,这样如果目标发生变化(鼠标光标总是发生这种情况),它就不会转动立即但平稳(有点像汽车)。
我尝试了这个计算:
dir_change -= (direction-my_angle)/Math.PI;
/Math.PI
旨在减少更改大小,-
应该产生差异。不起作用。
<强> I also made example on JSFiddle ,希望您不要因为不清楚而跳过这个问题。感谢您的帮助。
最佳答案
好吧,这是您的解决方案的有效 fiddle -> Fiddle Link <- .
请注意,我更改了一些变量名称,并添加了注释。
关于您的代码的一些问题:
负 Angular 是因为你用current-target
调用atan2 ,而不是 target-current
。您应该为atan2提供flyTo和flyPos之间的差异,因为这相当于从您所在的位置查看目标(这就是atan2的工作方式)。所以:
var my_angle = Math.atan2(flyPos[1]-flyTo[1],
flyPos[0]-flyTo[0]) -Math.PI;
应该是:
var my_angle = Math.atan2(flyTo[1]-flyPos[1],
flyTo[0]-flyPos[0]);
然后你就不应该担心 -PI
.
速度应该始终为正,因为它是一个标量,并且我们有方向(此外,负速度 = 负方向上的正速度)。
我已添加decelerate
和accelerate
方法,主要是为了避免文本试图到达目标时令人讨厌的“嗡嗡声”,并在微小位置之间不断来回移动。现在,当它靠近时它会减速,如果你远离它它会加速。
需要注意的一件小事:根据 MDN,您应该调用 setInterval
像这样:
setInterval( letter.flyAway, refreshEvery );
而不是使用自执行方法(而且它对眼睛来说也更容易)。
为了获得漂亮的转弯,我们要做的就是看着当前的方向,然后慢慢地转向目标方向。
以下简单的实现中可能存在错误(其中 dPhi
代表 delta phi,一个小 Angular ):
if ( Math.abs(angle_to_target - direction) > dPhi )
if (angle_to_target > direction)
direction += dPhi;
else
direction -= dPhi;
else
direction = angle_to_target;
例如,如果方向为 179 度,而目标为 181 度,则不会缩小 2 度间隙,而是围绕另一侧穿过 358 度。原因就是这样atan2
处理 Angular ,返回 -PI
之间的值和PI
。解决办法是添加2*PI
在几种情况下:
if (direction - Math.PI > angle_to_target )
angle_to_target += 2*Math.PI;
if (angle_to_target - Math.PI > direction )
direction += 2*Math.PI;
好了,正在摆弄 start
和stop
按钮将显示结果。
您可能想要添加随机 speed
/angle
到这个解决方案,但现在应该不难:)
关于javascript - 慢慢地将一个 Angular 变换到另一个 Angular ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20928558/