[粒子特效]吹散
原例:传送门
很久以前的例子了,现在重新学习粒子效果,练练手也好。
其实这里最有技术含量的是粒子的运动算法,至于setPixel之类的东西实在没什么好说的。
例一
粒子从图片的右边开始吹散,渐渐扩散到左边,运动轨迹是直线。
从程序的角度来看,每个粒子有自己的速度,比如最右边的速度为10,那么最左边为-50,速度大于0才让粒子运动,于是右边的粒子最先动,通过加速度的控制,慢慢的让左边的粒子运动。
再仔细看,右边的粒子初始速度很小,速度慢慢变快,一般来说,这种初始速度会保持在[0, 1]之间。来看个公式:
speed = range * Math.random() - (width - x);
speed表示粒子的速度,width表示图片的宽度,x表示粒子的x坐标。
很明显,这个公式会使右边的粒子先有正速度,其中range控制正速度的粒子有多大的范围,举个例子,图片宽度400,如果range为50,则x在 [350, 400] 的粒子会率先运动。刚才演示的range为1,现在来看个50的。
例二
粒子的运动是一种弧线轨迹,我就来说这是怎么实现的。
有没有想起正余弦曲线? 是不是很像? 没错,这就是原理。
package com.zhujl.object { public class Particle { public var x:Number; public var y:Number; public var color:Number; public var vx:Number; public var vy:Number; public var ax:Number; public var ay:Number; public var vr:Number; public var centerY:Number; public var radius:Number; public function Particle(x:Number, y:Number, color:uint, width:Number, centerY) { this.x = x; this.y = y; this.color = color; this.vx = Math.random() - (width - x); this.ax = 0.3; this.centerY = centerY; this.vr = y > centerY ? Math.PI : 0; this.radius = y > centerY ? y - centerY : centerY - y; } public function update():void { vx += ax; if(vx > 0){ x += vx; vr += 0.1; y = centerY + Math.cos(vr) * radius; } } } }
再来一个类似的:
源码如下:
package com.zhujl.object { public class Particle { public var x:Number; public var y:Number; public var color:Number; public var vx:Number; public var vy:Number; public var ax:Number; public var ay:Number; public var vr:Number; public var centerY:Number; public var radius:Number; public function Particle(x:Number, y:Number, color:uint, width:Number, centerY) { this.x = x; this.y = y; this.color = color; this.vx = Math.random() - (width - x); this.ax = 0.3; this.centerY = y; this.vr = 0; this.radius = 40; } public function update():void { vx += ax; if(vx > 0){ x += vx; y = centerY - Math.sin(vr) * radius; vr += 0.1; } } } }
要注意的是,这里我用sin,初始弧度统一为0,所以开始是一段上升的曲线,而flash的坐标系y轴是反过来的,所以centerY - Math.sin(vr) * radius才是向上。
例三:
这次不用正余弦了,改用抛物线
源码如下:
package com.zhujl.object { public class Particle { public var x:Number; public var y:Number; public var color:Number; public var vx:Number; public var vy:Number; public var ax:Number; public var ay:Number; public function Particle(x:Number, y:Number, color:uint, width:Number, centerY) { this.x = x; this.y = y; this.color = color; this.vx = 1 * Math.random() - (width - x); this.ax = 0.3; this.vy = -5; this.ay = 0.05; } public function update():void { vx += ax; if(vx > 0){ x += vx; vy += ay; y += vy; } } } }