发个简单怡情的--粒子随机运动
源码:https://files.cnblogs.com/flash3d/brownianAdvance.rar
首先要谢谢大哥大姐门提出的意见,老版本的问题,主要还是执行效率。在粒子爆发的时候,大量的开辟内存,还有长时间执行,粒子数量没有加以控制,造成卡机严重。。
这里本人用面向对象的方法重写了一遍代码,使用缓存来储存原本消失的粒子。下面是重写后的代码
Item.as
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
/**
* ...
* @author boycy815
*/
public class Item extends Shape
{
private var fx:Number;
private var vx:Number;
private var fy:Number;
private var vy:Number;
public function Item():void
{
this.graphics.beginFill(0xffffff*Math.random());//随机绘制圆的颜色
this.graphics.drawCircle(-1,-1,2);//画一个半径2,位置是(-1,-1)的圆,这个圆的圆心正好是注册点
this.graphics.endFill();//结束绘制
}
public function init(setx:Number,setY:Number):void
{
fx=0;//x方向的力,也可以理解成加速度
vx=0;//x方向的速度
fy=0;//y方向的力
vy = 0;//y方向的速度
this.x = setx;
this.y = setY;//以上两句设置初始位置
this.addEventListener(Event.ENTER_FRAME,go);//为该对象添加ENTER_FRAME事件监听
}
private function go(e:Event):void
{
fx=Math.random()*2-1;//随机产生一个x方向的力,随机值范围(-1,1)
fx-=vx*0.05;//为x方向添加一个阻力,该阻力和x方向速度成正比(这个处理是防止粒子移动过快)
vx+=fx;//将加速度作用到速度上
this.x+=vx;//再将速度作用于位移
if (this.x<1||this.x>549)//边界判断,超出边界,执行一下自杀代码
{
if (this.parent != null)
{
this.parent.removeChild(this);//告诉自己的妈妈,叫她把自己从舞台删了
}
this.removeEventListener(Event.ENTER_FRAME, go);//把这个不断执行的函数也删了
ShapeMannager.addItem(this);//把自己交给缓存储存
ShapeMannager.total--;//舞台上的数量减1
return;//直接跳出这个函数,下面就不执行了
}
//以下是y方向,同理
fy=Math.random()*2-1;
fy-=vy*0.05;
vy+=fy;
this.y+=vy;
if (this.y<1||this.y>399)
{
if (this.parent != null)
{
this.parent.removeChild(this);//告诉自己的妈妈,叫她把自己从舞台删了
}
this.removeEventListener(Event.ENTER_FRAME, go);
ShapeMannager.addItem(this);
ShapeMannager.total--;
return;
}
}
}
}
ShapeMannager.as
package
{
/**
* ...
* @author boycy815
*/
public class ShapeMannager//一个管理缓存的类,从舞台消失的粒子暂时保存在缓存
{
private static var _cashe:Array = new Array();//缓存数组
public static var total:int = 0;//计数在场粒子数量的全局变量
public static function getItem():Item//获取一个粒子
{
if (_cashe.length == 0)//如果缓存空了,那么返回新建的粒子
{
return (new Item());
}
else//如果缓存不为空,返回缓存末尾的粒子,并从缓存删除
{
return _cashe.pop();
}
}
public static function addItem(it:Item):void//往缓存内添加粒子
{
_cashe.push(it);
}
}
}
ParticleStorm.as
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* ...
* @author boycy815
*/
public class ParticleStorm extends MovieClip
{
public function ParticleStorm():void
{
var timer:Timer=new Timer(1000);//声明并初始化一个1秒发生一次的时间发生器
timer.addEventListener(TimerEvent.TIMER, addIt);//为时间发生器的Timer事件添加事件,以使每1秒能执行一次addIt
timer.start();//这句不能忘,时间器需要执行开始,才能运行
}
private function addIt(e:Event):void//这个函数每1秒被调用一次,作用是在随机位置为舞台补充随机数量的新粒子
{
if (ShapeMannager.total < 256)//这句是新加的,一个全局计数total,用来计数在场的所有粒子,要是在场粒子超过256个,就不执行添加
{
var n:int = 0;//用于循环的临时变量
var it:Item;//用来临时储存和操作粒子的变量
var initX:Number = Math.random() * 550;//随机发生一个舞台上的位置
var initY:Number = Math.random() * 400;//同上
var num:int = int(Math.random() * 512);//确定随机添加的数量
for(n=0;n<num;n++)//每次发生一次,执行num次循环,每循环一次,将产生一个粒子
{
it=ShapeMannager.getItem();//新建或者从缓存提取一个粒子
it.init(initX,initY);//设定初始位置并初始化
this.addChild(it);//将粒子添加到舞台
}
ShapeMannager.total+=num;//在场计数添加num
}
}
}
}
总共三个as文件,其中ParticleStorm.as为文档类
以下是老版本的代码----------------------------------------------------------------------------------------------------
http://files.cnblogs.com/flash3d/brownian.rar
flash会每隔5秒爆发512个粒子,粒子进行无规则的运动,超出运动边界的粒子将会被删除。哈哈,就是这么个效果。代码非常简单,利用了一些牛顿物理学的知识。
很久没有发表文章了,今天突然兴起,做了这么个东西,谈不上什么高科技,但还算有趣。下面我们就把制作过程和代码讲解下。
第一步:
建立一个库元件,影片剪辑类型,进入编辑。在第一帧写下如下代码
this.graphics.beginFill(0xffffff*Math.random());//随机绘制圆的颜色
this.graphics.drawCircle(-1,-1,2);//画一个半径2,位置是(-1,-1)的圆,这个圆的圆心正好是注册点
this.graphics.endFill();//结束绘制
var fx:Number=0;//x方向的力,也可以理解成加速度
var vx:Number=0;//x方向的速度
var fy:Number=0;//y方向的力
var vy:Number=0;//y方向的速度
this.addEventListener(Event.ENTER_FRAME,go);//为该对象添加ENTER_FRAME事件监听
function go(e:Event):void {//事件发生的函数,每1帧周期执行一次
fx=Math.random()*2-1;//随机产生一个x方向的力,随机值范围(-1,1)
fx-=vx*0.05;//为x方向添加一个阻力,该阻力和x方向速度成正比(这个处理是防止粒子移动过快)
vx+=fx;//将加速度作用到速度上
this.x+=vx;//再将速度作用于位移
if (this.x<1||this.x>549) {//边界判断,超出边界,执行一下自杀代码
this.parent.removeChild(this);//告诉自己的妈妈,叫她把自己从舞台删了
this.removeEventListener(Event.ENTER_FRAME,go);//把这个不断执行的函数也删了
return;//直接跳出这个函数,下面就不执行了
}
//以下是y方向,同理
fy=Math.random()*2-1;
fy-=vy*0.05;
vy+=fy;
this.y+=vy;
if (this.y<1||this.y>399) {
this.parent.removeChild(this);
this.removeEventListener(Event.ENTER_FRAME,go);
return;
}
第二步:
退到主场景,在库里面把刚才建立的元件执行链接,链接出来的类名是Item。然后在主场景画一个灰色的和舞台大小相同位置00的矩形作为背景。接下来在主场景第一帧写下如下代码。
var it:Item;//声明一个Item类型的变量
var timer:Timer=new Timer(5000);//声明并初始化一个5秒发生一次的时间发生器
timer.addEventListener(TimerEvent.TIMER,addIt);//为时间发生器的Timer事件添加事件,以使每五秒能执行一次addIt
function addIt(e:Event):void//这个函数每5秒被调用一次,作用是在随机位置为舞台补充新的粒子
{
var n:int=0;//用于循环的临时变量
var initX:Number=Math.random()*550;//随机发生一个舞台上的位置
var initY:Number=Math.random()*400;//同上
for(n=0;n<512;n++)//每次发生一次,执行512次循环,每循环一次,将产生一个粒子
{
it=new Item();//新建一个粒子,这个Item就是刚咱们在库里面链接出来的
it.x=initX;//设定初始位置
it.y=initY;//同上,这个初始位置是刚随机发生的
this.addChild(it);//将粒子添加到舞台
}
}
timer.start();//这句不能忘,时间器需要执行开始,才能运行
addIt(new Event("timer"));//为了打发前五秒无聊的时间,我们可以先把addIt函数运行一遍,注意参数噢。}
然后测试运行下!恩 效果是不是不错呢O(∩_∩)O!!