Flint Particle粒子入门教程

这个是Flint Particle粒子入门教程,as3 flash Particle下雪效果,下面是效果
[b]【[url]http://www.newflash3d.com[/url]---flash3D先锋队:北京贝武易科技公司】[/b]
有疑问请联系我QQ:363596350
Flint Particle粒子在线帮助文档:
[url]http://flintparticles.org/docs/[/url]
[flash=500,400]http://www.newflash3d.com//blogfile/swf/Snowfall.swf[/flash]
由于开发的需要,我们的很多实例都是建立在Flex平台的
首先我们需要建立一个Flex的画布
具体请参考我们的博客文章:Flex画布的建立。
我们这里的画布其实是我们自己写的一个Flex的组件,我们把它发到myCanvas3D的包里,它的代码如下:
Canvas3D.as
package myCanvas3D
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Rectangle;

import mx.core.UIComponent;
import mx.effects.easing.Back;


public class Canvas3D extends UIComponent
{
private var paperSprite:Sprite;
private var backgroundSprite:Sprite;
private var clipRect:Rectangle;

private var _backgroundColor:uint = 0x000000;
private var _backgroundAlpha:Number = 1;

public function Canvas3D()
{
super();
init();
}

private function init():void
{
clipRect = new Rectangle();
}

override protected function createChildren():void
{
super.createChildren();
backgroundSprite = new Sprite();
backgroundSprite.cacheAsBitmap = true;

paperSprite = new Sprite();

addChild(backgroundSprite);
addChild(paperSprite);
}

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
drawBackground();

var hw:Number = 0;
var hh:Number = 0;

paperSprite.x = hw;
paperSprite.y = hh;

clipRect.x = 0;
clipRect.y = 0;
clipRect.width = unscaledWidth;
clipRect.height = unscaledHeight;

scrollRect = clipRect;
}

protected function drawBackground():void
{
if(backgroundSprite){
var g:Graphics = backgroundSprite.graphics;
g.clear();
g.beginFill(backgroundColor, _backgroundAlpha);
g.drawRect(0,0,unscaledWidth,unscaledHeight);
g.endFill();
}
}

public function set backgroundColor(bgColor:uint):void
{
_backgroundColor = bgColor;
drawBackground();
}

public function get backgroundColor():uint
{
return _backgroundColor;
}

public function set backgroundAlpha(alpha:Number):void
{
_backgroundAlpha = alpha;
}

public function get backgroundAlpha():Number
{
return _backgroundAlpha;
}

public function get canvas():Sprite
{
return paperSprite;
}

}
}

我们通过这个方法在Flex里建立这个组件。
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:myCanvas3D="*"  layout="absolute" xmlns:myCanvas3D1="myCanvas3D.*">
<myCanvas3D1:Canvas3D width="500" height="400" id="mycanvas3d" backgroundColor="0x000000"/>

这样就生成了一个黑色的Canvas3D画布,他的尺寸为500X400的。
那样我们的Sprite物体就可以加到它上面了。
首先我们要做的第一步是把Flint Particle的类包复制到我们的项目文件包里。如图

[img]/upload/attachment/67356/b2c1b39d-8c17-3f7c-8be2-cc5f425b0263.jpg[/img]
下面我们是通过类的形式来实现下雪的效果,首先我们建立一个Snowfall粒子发射器,它继承自Emitter2D发射器。代码如下:
package
{
import flash.geom.Point;
import org.flintparticles.common.counters.*;
import org.flintparticles.common.displayObjects.RadialDot;
import org.flintparticles.common.initializers.*;
import org.flintparticles.twoD.actions.*;
import org.flintparticles.twoD.emitters.Emitter2D;
import org.flintparticles.twoD.initializers.*;
import org.flintparticles.twoD.zones.*;

public class Snowfall extends Emitter2D
{
public function Snowfall()
{
counter = new Steady( 100 );//每秒发发射的粒子数为100

addInitializer( new ImageClass( RadialDot, 2 ) );
addInitializer( new Position( new LineZone( new Point( -5, -5 ), new Point( 505, -5 ) ) ) );
addInitializer( new Velocity( new PointZone( new Point( 0, 65 ) ) ) );
addInitializer( new ScaleImageInit( 0.75, 2 ) );

addAction( new Move() );
addAction( new DeathZone( new RectangleZone( -10, -10, 520, 420 ), true ) );
addAction( new RandomDrift( 15, 15 ) );
}
}
}

下面我们分析一下这个Snowfall粒子发射器的性质。
第一步,引入需要应用到的类:

import flash.geom.Point;
import org.flintparticles.common.counters.*;
import org.flintparticles.common.displayObjects.RadialDot;
import org.flintparticles.common.initializers.*;
import org.flintparticles.twoD.actions.*;
import org.flintparticles.twoD.emitters.Emitter2D;
import org.flintparticles.twoD.initializers.*;
import org.flintparticles.twoD.zones.*;

以后我们再说明这些类的意义。
public class Snowfall extends Emitter2D

Snowfall类继承自Emitter2D类。
下一句:
counter = new Steady( 100 );

Steady,这里是用了一个稳定类型的counter。(counter是接口,Steady是实现接口的一个类)。这里需要注意的Flint粒子系统给我们提供了许多中类型的counter,当然它们都实现了counter接口的所有方法。
counter(数量)是Emitter(也就是Snowfall对象)的一个属性。
Steady类是继承了counter接口的类,它能直接实例化为counter对象。
我们这里是:接口 接口 = new 实例化类(); 这样可以该接口所实例化类的对象。
我们进入counter属性的定义(在Emitter类里)
		public function get counter():Counter
{
return _counter;
}
public function set counter( value:Counter ):void
{
_counter = value;
}

我们会注意到counter是一个Set get存取器,通过这个counter方法我们可以存取或获得一个counter类型的对象。
关于接口和实例化的类,大家可以深入去学习一下。
counter接口的代码如下:
package org.flintparticles.common.counters 
{
import org.flintparticles.common.emitters.Emitter;

/**
* The Counter interface must be implemented by all counters.
*
* <p>A counter is a class that tells an emitter how many particles to
* emit at any time. The two methods control the rate of emission of particles
* when the emitter starts and every frame thereafter.</p>
*
* <p>A counter is directly associated with an emitter. A counter is set for
* an emitter by assigning it to the emitter's counter property.</p>
*
* @see org.flintparticles.common.emitters.Emitter#counter
*/
public interface Counter
{
/**
* The startEmitter method is called when the emitter starts.
*
* <p>This method is called within the emitter's start method
* and need not be called by the user.</p>
*
* @param emitter The emitter.
* @return The number of particles the emitter should emit when it starts.
*/
function startEmitter( emitter:Emitter ):uint;

/**
* The updateEmitter method is called every frame after the
* emitter has started.
*
* <p>This method is called within the emitter's update loop and need not
* be called by the user.</p>
*
* @param emitter The emitter
* @param time The time, in seconds, since the previous call to this method.
* @return The number of particles the emitter should emit
* at this time.
*/
function updateEmitter( emitter:Emitter, time:Number ):uint;

/**
* Stops the emitter from emitting particles
*/
function stop():void;

/**
* Resumes the emitter after a stop
*/
function resume():void;

}
}

它给我们提供了4个需要实现的接口方法,它们分别是:
[b]startEmitter(开始发射):[/b]发射器开始发射的时候就调用startEmitter方法,它自动就会执行,不需要我们手动去调用。emitter发射器是它的参数,它返回已经发射的粒子数;
[b]updateEmitter(更新):[/b]updateEmitter方法在粒子发射器发射后的每帧执行的时候都会被调用。该方法自动执行,参数为emitter粒子发射器和time时间,返回到当时的粒子发射数量;
[b]stop(停止发射):[/b]停止发射粒子;
[b]resume(重启):[/b]重新开始发送粒子。

下面我们需要设置粒子的各种属性:
position(位置), velocity(速度), image(显示图像) 和 color(颜色)
我们通过给粒子增加initializer(初始化属性)来设定粒子的这些属性。
因为这里我们是用了一个DisplayObjectEmitter(显示物体类型发射器),所以发射器会为每个粒子生成一个DisplayObject(显示物体)。

[b]关于粒子的Initializer(初始化器):[/b]

第一步,我们需要告诉粒子是它应该是什么样的。我们用一个ImageClass initializer(图像类型初始化器)来告诉Emitter如何去实现发射的粒子物体类型。
我们来看看Initializer(初始化物体),Flint粒子定义了一个Initializer接口。
在Flex里我们需要把图像embed(植入)到工作区里,然后以类的方式应用。方法如下:
var imgClass:ImageClass = new ImageClass( MyImageClass );

然而这里我们用Flint Particle粒子图像库里自带的RadialDot class(辐射点图类)来作为ImageClass的资源。RadialDot class是一个简单的圆点渐变图。RadialDot继承自Shape。我们可以参阅它的构造函数。
var imgClass:ImageClass = new ImageClass( RadialDot, 2 );

最后把ImageClass initializer加到emitter。
emitter.addInitializer( imgClass );

省去一些步骤,结果如下:
emitter.addInitializer( new ImageClass( RadialDot, 2 ) );


[b]关于区域(Zone):[/b]

下面我们来讨论一下粒子的区域(Zone),位置初始化器(Position initializer)用到区域(Zone)。Zone是一个粒子定义的区域。这个其实是粒子的发射形状区域。这里我们选择了线性发射形状(LineZone),发射区域的代码如下:
emitter.addInitializer( new Position( new LineZone( new Point( -5, -5 ), new Point( 505, -5 ) ) ) );


我们给粒子发射器(emitter)增加一个速度初始化器(Velocity initializer),让粒子能动起来。代码:
emitter.addInitializer( new Velocity( new PointZone( new Point( 0, 65 ) ) ) );


[b]关于粒子行为(Actions)[/b]

这时候我们还是没有看到粒子的执行,我们还需要给粒子发射器增加一些行为(Actions)。为了开始作用,我们只需要给粒子增加一个行为(Actions),虽然这里我们的粒子有了位置和速度,但是还需要运动行为(Move action)来实时的更新粒子的位置和速度信息。
emitter.addAction( new Move() );


上面的设置都完成后就可以开始发射粒子了,代码:
emitter.start();


这个过程对于初学者有一定的难度,但是耐心消化一下,问题还是能解决的,祝您成功!顺祝大家新年快乐!

运行项目后我们会看到长长的粒子落了下来,我们需要设置粒子的结束和寿命值。
我们用一个销毁区域(DeathZone)来销毁多余的,不在该区域里的粒子。代码:
var dzone:RectangleZone = new RectangleZone( -10, -10, 520, 420 );
var deathZone:DeathZone = new DeathZone( dzone, true );
emitter.addAction( deathZone );

缩简一下:
emitter.addAction( new DeathZone( new RectangleZone( -10, -10, 520, 420 ), true ) );

我们可以通过改变这两个点所包括的区域,不在这两个点的区域里的其他粒子都不显示了。

[b]粒子的随机性(让粒子更自然):[/b]

我们给粒子增加一个缩放初始器(ScaleImageInit initializer)来让粒子产生随机大小。
emitter.addInitializer( new ScaleImageInit( 0.75, 2 ) );

ScaleImageInit方法带两个参数(最小缩放值,最大缩放值)

总结一下:addInitializer(初始化器),它的参数必须是初始化器。

增加随机运动:
emitter.addAction( new RandomDrift( 15, 15 ) );


[b]先运行(runAhead):[/b]

为了让影片运行的时候粒子就布满了画布,我们需要给粒子一个先发射时间,代码:
emitter.runAhead( 10 );


根据以上分析,我们得出雪花粒子的类Snowfall.as

Flex mxml代码:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:myCanvas3D="*" layout="absolute" xmlns:myCanvas3D1="myCanvas3D.*" applicationComplete="init()">
<mx:Script>
<![CDATA[
import flash.geom.Point;
import org.flintparticles.twoD.renderers.*;

var emitter:Snowfall;
var renderer:DisplayObjectRenderer;

public function init(){
renderer = new DisplayObjectRenderer();
emitter= new Snowfall();
renderer.addEmitter( emitter );
mycanvas3d.canvas.addChild( renderer );//注意这里把render物体加入到mycanvas3d.canvas
emitter.start();
emitter.runAhead( 10 );
}

]]>
</mx:Script>
<myCanvas3D1:Canvas3D width="500" height="400" id="mycanvas3d" backgroundColor="0x000000"/>
</mx:Application>


恩,基本上就到这里了!更多的知识需要我们进一步深入研究,努力啊!
[b]【[url]http://www.newflash3d.com[/url]---flash3D先锋队:北京贝武易科技公司】[/b]
有疑问请联系我QQ:363596350
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值