查看: 2245|回复: 0
打印 上一主题 下一主题

[as3基础应用]发个简单怡情的--粒子随机运动

[复制链接]
.    

3797

主题

11

听众

5万

积分

首席设计师

Rank: 8Rank: 8

纳金币
32328
精华
41

活跃会员 优秀版主 荣誉管理 论坛元老

跳转到指定楼层
楼主
发表于 2013-3-20 10:44:27 |只看该作者 |倒序浏览
演示地址:http://hong-ming.cn/flash/ParticleStorm.swf
首先要谢谢大哥大姐门提出的意见,老版本的问题,主要还是执行效率。在粒子爆发的时候,大量的开辟内存,还有长时间执行,粒子数量没有加以控制,造成卡机严重。。
这里本人用面向对象的方法重写了一遍代码,使用缓存来储存原本消失的粒子。下面是重写后的代码
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为文档类
以下是老版本的代码----------------------------------------------------------------------------------------------------
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!!
【来源:互联网】
更多精彩教程,尽在web3D纳金网http://www.narkii.com/college/ 演示地址:http://hong-ming.cn/flash/ParticleStorm.swf
首先要谢谢大哥大姐门提出的意见,老版本的问题,主要还是执行效率。在粒子爆发的时候,大量的开辟内存,还有长时间执行,粒子数量没有加以控制,造成卡机严重。。
这里本人用面向对象的方法重写了一遍代码,使用缓存来储存原本消失的粒子。下面是重写后的代码
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为文档类
以下是老版本的代码----------------------------------------------------------------------------------------------------
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!!
【来源:互联网】
更多精彩教程,尽在web3D纳金网http://www.narkii.com/college/
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-11-27 21:13 , Processed in 0.103035 second(s), 33 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部