2013-02-26 106 views
0

我在画布上创建了一个简单的粒子实验。现在,我希望他们能够从画布上的鼠标滚轮“逃跑”。检测距鼠标的距离不是问题,但是如何编写它们的行为?粒子从鼠标“逃跑”

每个粒子被创建为以下:

var particle = { 
     x: Math.floor(Math.random() * width), 
     y: Math.floor(Math.random() * height), 
     xVel: Math.random() * 10 - 5, 
     yVel: Math.random() * 10 - 5, 
    } 

所以我想我也应该保存的方向以某种方式,并且如果从指针的距离为< X,扭转方向?也许也保存旧的速度,并在离开时慢慢减少它?

如何检测的方向?

回答

1

速度(xVel,yVel,一起)是2D矢量。鼠标和粒子之间的距离也是如此。 A vector包含方向和大小。所以你需要一个与鼠标位置和粒子位置不同的矢量。

var posRelativeToMouse = { 
    x: particle.x - mousPosX, 
    y: particle.y - mousPosY 
}; 

所以少量的x和y意味着粒子接近老鼠,大意味着它很远。

接下来,我们需要弄清楚这些数字应该是如何影响粒子的速度。所以我们需要2件事。

什么方向我们推他们?

我们已经有这样的居多。 posRelativeToMouse是一个有我们想要的方向的向量。我们只是规范化它,这意味着将矢量的长度设置为1.为此,我们将每个组件除以矢量的当前长度。该向量的长度始终为distance,从粒子到鼠标。

var distance = Math.sqrt(
    posRelativeToMouse.x * posRelativeToMouse.x + 
    posRelativeToMouse.y * posRelativeToMouse.y 
); 
var forceDirection = { 
    x: posRelativeToMouse.x/distance, 
    y: posRelativeToMouse.y/distance, 
}; 

有多难我们推颗粒?

这是距离的倒数。关闭意味着大推动,远意味着一点点推动。因此,让我们重新使用我们上面计算出的distance

// distance past which the force is zero 
var maxDistance = 1000; 

// convert (0...maxDistance) range into a (1...0). 
// Close is near 1, far is near 0 
// for example: 
// 250 => 0.75 
// 100 => 0.9 
// 10 => 0.99 
var force = (maxDistance - distance)/maxDistance; 

// if we went below zero, set it to zero. 
if (force < 0) force = 0; 

好的,我们有一个方向,我们有力量。剩下的就是将其应用于粒子速度。

particle.xVel += forceDirection.x * force * timeElapsedSinceLastFrame; 
particle.yVel += forceDirection.y * force * timeElapsedSinceLastFrame; 

并假设你是动画的位置由xVel/yVel每一帧,你现在应该有通过鼠标被推开颗粒。

+0

很好,但现在我有另一个问题。如何让粒子“回到”之前的速度?因为在离开鼠标后,他们开始用新的速度+ force – mjanisz1 2013-02-27 20:20:50

+0

@ mjanisz1开始疯狂,这取决于你希望他们如何表现。但是这听起来有点像你想要对粒子产生阻力,这意味着它们随着时间的推移会自行减速?一个简单而粗略的方法是在每一帧上使速度变得更小一些。像'particle.xVel * = 0.99'(当然也是'yVel')。这意味着粒子每帧将失去1%的速度,如果没有其他力量作用于其上,最终应该接近零。您可以将“0.99”值调整为任何可以提供所需拖动量的值。 – 2013-02-27 21:56:53

+0

非常感谢很多人没有想到的乘法(简单的事情是最好也是最难想象的)。如果'force == 0 && xVel> xVelOriginal'比第一个速度乘以0.99!希望它的作品:)谢谢你很多! – mjanisz1 2013-02-28 18:48:42

1

可以通过从鼠标的位置减去粒子的位置获得一个矢量v,

然后就可以发现这个矢量的大小我的拍摄的sqrt(X^2 + Y^2)

通过将v除以量值,您可以获得希望粒子走向的单位向量。例如

假设我在列表中有U,每个具有x和y场10级的颗粒。

我能得到它的每个粒子V向量通过将v =(xpart - mousepart,ypart - mousepart)

,那么你需要采取开方找到幅度VMAG(VX^2 + VY^2)

则获得vunit =(VX/VMAG,VY/VMAG)

这是载体 “远离鼠标”。

剩下的就留给detemining要在移动速度,并确保你反弹的墙壁和这样的。

我在github上开源一个类似的项目: https://github.com/dmitrymakhnin/JavaParticleSystem/blob/master/Main.java