网络上搜索到提供下载的AS3粒子效果的源代码很少,所以自己发一个,希望对需要的人有帮助。
以前在做一个flash AS3效果的时候需要粒子效果,就在网上找类似的,终于让我找到了一个,以下是几个关于粒子效果的讲解链接
http://www.flashas.net/bbs/read-htm-tid-1549.html
http://www.klstudio.com/post/194.html
http://www.ryan-liu.com/blog/?p=540
http://bbs.actionscript3.cn/thread-23124-1-1.html
http://www.ryan-liu.com/blog/?p=555
http://www.ryan-liu.com/blog/?p=550
其中一个效果的源代码页地址
http://bbs.actionscript3.cn/thread-23210-1-1.html
可惜这个效果我还做不到,水平有限,没办法,不过我需要的也是个类似的效果。
看了这篇贴后自己研究,终于研究出来了,累死。。。
效果http://www.michaellee23.com/info/info_67.html
后来我觉得这样向一个方向运动可以改成向四面八方的运动,开始研究,虽说是研究但也就是改了改代码,也不算什么研究,下面是效果
大概方法我最开始提到的几个地址里都能找到,就是先用循环获得一张load近来的位图(或mc)各个象素点的颜色和alpha通道透明度等信息,然后保存进一个数组里,为了实现从不透明到透明的效果,我把颜色、透明度、x、y坐标等信息存在了自己写的一个类实例里,然后把类实例保存到数组里。
取颜色的方法就是bitmapdata类的getpixel()或getpixel32(),记住,这个bitmapdata实例是一个源实例,用完后就没用了(可以用bitmapdata类的去掉),因为图片要向四周扩散,所以真正要操作的bitmapdata实例要比图片本身大一圈。
然后在enterframe里放个循环把数组里的实例一个一个取出来,把相应点的颜色用bitmapdata类的setpixel()或setpixel32()方法把颜色设置到另一个真正用来显示和操作的bitmapdata实例上,这个bitmapdata实例真正和源图象颜色信息一样的地方是中心部分,刚才我说过这个实例比源图象大一圈,为了使象素粒子产生从有到无的效果。
bitmapdata实例并不直接显示出来,需要用bitmap显示出来,方法是“bms:Bitmap=new Bitmap(bitmapdata实例)”。
上面的教程说要用bitmapdata.lock()
我做的效果需要先填充0或0x00000000
然后用for循环对各个象素点进行setpixel32()操作
最后用bitmapdata.unlock()
据说这样会节省资源。
希望大家先耐心看看上面的几个别人写的教程,看明白了以后就可以自己写了,如果直接用代码的话以后还是不会,我写了这么多其实没什么重点,写的不好,也许大家都看不懂,其实我做的这个效果只用了一个bitmapdata类,然后用了几个这个类方法。不过里面用到了一个把uint类型和16进制数字的转换,这个是我在经典论坛上提问后别人告诉我的。
本来想放上来个压缩包大家直接下载,但不行,估计这个空间不让下载,就把源代码贴出来了
fla文件第一帧代码:
import flash.display.*;
import Simple2D;//此类用于保存相应单个粒子的信息,颜色,透明度等
var Arr_tp:Array = [];//保存Simple2D实例的数组
var Out:int=0;//透明度为0或位置超出范围的栗子数量
var bm:BitmapData = new BitmapData(pic.width, pic.height);
bm.draw(pic);
var bm1:BitmapData = new BitmapData(pic.width+400, pic.height+400,true,0x00000000);//实际需要操作的bitmapdata
var bms:Bitmap=new Bitmap(bm1);
addChild(bms);//把bitmap加到显示列表中
bms.x=0;
bms.y=0;for(var i:int=0;i<pic.width;i++){
for(var j:int=0;j<pic.height;j++){
if(bm.getPixel32(i,j)!=0){//如果象素不透明才保存进数组
bm1.setPixel32(i+200,j+200,bm.getPixel32(i,j));//第一次设置要bitmapdata的象素信息(x,y,颜色)
var tp:Simple2D = new Simple2D(i+200,j+200,(Math.random() - Math.random()) * 5,(Math.random() - Math.random()) * 5, 0.5+Math.random()*5, bm.getPixel32(i,j));
Arr_tp.push(tp);
}
}
}
bm.dispose();//释放bm占用的内存
var rect:Rectangle = new Rectangle(0,0,bms.width,bms.height);//获得bms的矩形框
/////////////////////////////////////////////给按钮添加click事件
btn.addEventListener(MouseEvent.CLICK,gotobreak);
function gotobreak(event:MouseEvent){
bms.addEventListener(Event.ENTER_FRAME, loop);//添加enterframe事件
}
//////////////////////////////////////////////////////////////function loop(e:Event) {
bm1.lock();
bm1.fillRect(rect,0);
for(var i:int=0;i<Arr_tp.length;i++){
var tp:Simple2D = Arr_tp[i] as Simple2D;
tp.update();
if(!tp.isOut){//如果没超出范围再执行
if (tp.x <= 0) {
tp.isOut = true
}
if (tp.x >= bm1.width) {
tp.isOut = true
}
if (tp.y <= 0) {
tp.isOut = true
}
if (tp.y >= bm1.height) {
tp.isOut = true
}
if (tp.get_alpha() == "00"){//透明度为0
tp.isOut = true
}//tp.isOut = true 代表超出了范围
if (tp.isOut) {
tp.Allcolor=0;
tp.x=0;
tp.y=0;
tp.vx=0;
tp.vy=0;
tp.mass=0;
Out++;//超出范围的粒子总数+1
}
}
bm1.setPixel32(tp.x,tp.y,tp.Allcolor);//设置相应点的颜色
}
bm1.unlock();
if(Out>=Arr_tp.length){//如果所有被操作的粒子都超出了范围就删除enterframe
del_loop();
}
}function del_loop():void{//删除enterframe
bms.removeEventListener(Event.ENTER_FRAME,loop);
}
在场景中放个mc,里面放个文字(可读性取消锯齿)
Simple2D.as文件代码
package
{
/**
* @author Ryan Liu | www.ryan-liu.com
* @since 2009-3-19 22:41
* 此类原始代码来源于www.ryan-liu.com提供的代码
* @since 2009-7-7 22:41 by www.michaellee23.com
*/
public class Simple2D
{
public var x:Number;//x坐标,每次update后都会变
public var y:Number;//y坐标,每次update后都会变
public var vx:Number;//x坐标增量即移动距离,有正有负,这样就能想四周扩散,不变
public var vy:Number;//y坐标增量即移动距离,有正有负,这样就能想四周扩散,不变
public var mass:Number;//透明度改变程度
private var alpha:String;//透明度的16进制字符串形式,透明度为100%时,uint格式为255,16进制格式为ff
private var color:String;//颜色的16进制字符串形式,rgb三个颜色通道的色值的16进制格式,例如:ff0000
public var Allcolor:uint;//带透明度颜色的uint格式数值,如654387
public var isOut:Boolean;//是否超出控制范围,超出为true,没超出为false
public function Simple2D(particleX:Number = 0, particleY:Number = 0, speedX:Number = 0, speedY:Number = 0, pMass:Number = 1, pAllcolor:uint = 0)
{
x = particleX;
y = particleY;
vx = speedX;
vy = speedY;
mass = pMass;
Allcolor = pAllcolor;
set_alpha();
set_color();
isOut=false;
}
public function update() {
x += vx;
y += vy;
var alpha_num:Number = parseInt(alpha,16) - mass * 3;
if(alpha_num<=0){
alpha_num=0;
}
alpha=alpha_num.toString(16);
alpha=( "0" + alpha ).substr ( -2 );
set_Allcolor();
}
public function set_alpha():void{//设置alpha通道16进制字符串形式
var s_color:String = Allcolor.toString(16);
alpha = s_color.substring ( 0 , 2 );
alpha = ( "0" + alpha ).substr ( -2 );
}
public function set_color():void{//设置rgb三色通道16进制字符串形式
var s_color:String = Allcolor.toString(16);
color=s_color.substring ( 2 , s_color.length );
}
public function set_Allcolor():void{//将透明度和颜色组合,成为带alpha透明度通道的颜色格式
Allcolor=new Number ( "0x"+ alpha+color );
}
public function get_Allcolor():uint{//这个方法好象没什么用。。。。
return Allcolor;
}
public function get_alpha():String{
return alpha;
}
}
}
就这两个文件,大家可以再优化一下,比如写成文档类或更精简点,本人水平有限。
好象又可以下载了。源代码下载