away3d传送门特效

away3d 4.0加入特效系统后,做比较炫的特效已经不是什么难事,away3d官方已经基于内置的particle system做了几个挺炫的粒子特效,需要的可以查看github中实例源码。这个传送门特效且作为away3d 粒子系统练手的的另一个实例。

简单说下,这个特效由三个独立的部分组成,转动的符文圆盘、向上发射的半透明光及不断从符文盘向上浮动的颗粒。效果图如下:

Snip201303_3

废话不说,直接上代码解释。

首先,必须准备三个部分的纹理和材质了。分别是符文圆盘、光辉、浮动粒子的纹理,在本教程最后提供的源码里有相应的纹理。

[Embed(source="../assets/pan.png")]
public  var panTexture:Class;

[Embed(source="../assets/light.png")]
public  var lightTexture:Class;

[Embed(source="../assets/blueball.png")]
public  var blueballTexture:Class;

材质拆分成五个部分,分别对应五种不同的粒子mesh。简单说为什么有五种,因为:1圆盘+3光辉+1浮动粒子串。粒子对应的五种material、mesh、animator等的声明如下,它们之间的关系我们将在后面代码解释。

//materials
private var matPan:TextureMaterial;
private var matLight1:TextureMaterial;
private var matLight2:TextureMaterial;
private var matLight3:TextureMaterial;
private var matBall:TextureMaterial;

//particle objects
private var particleAnimationSet1:ParticleAnimationSet;
private var particleAnimationSet2:ParticleAnimationSet;
private var particleAnimationSet3:ParticleAnimationSet;
private var particleAnimationSet4:ParticleAnimationSet;
private var particleAnimationSet5:ParticleAnimationSet;
private var particleGeometry1:ParticleGeometry;
private var particleGeometry2:ParticleGeometry;
private var particleGeometry3:ParticleGeometry;
private var particleGeometry4:ParticleGeometry;
private var particleGeometry5:ParticleGeometry;

// scene objects
private var particleMesh1:Mesh;
private var particleMesh2:Mesh;
private var particleMesh3:Mesh;
private var particleMesh4:Mesh;
private var particleMesh5:Mesh;
private var animator1:ParticleAnimator;
private var animator2:ParticleAnimator;
private var animator3:ParticleAnimator;
private var animator4:ParticleAnimator;
private var animator5:ParticleAnimator;

接着就是初始化引擎了,为了便于理解,采用跟官方一样的方法,顺便贴出代码。

//engine variables
private var scene:Scene3D;
private var camera:Camera3D;
private var view:View3D;
private var cameraController:HoverController;

//signature variables
private var Signature:Sprite;
private var SignatureBitmap:Bitmap;

//navigation variables
private var _move:Boolean = false;
private var _lastPanAngle:Number;
private var _lastTiltAngle:Number;
private var _lastMouseX:Number;
private var _lastMouseY:Number;

/**
 * Initialise the engine
 */
private function initEngine():void
{
	stage.scaleMode = StageScaleMode.NO_SCALE;
	stage.align = StageAlign.TOP_LEFT;

	scene = new Scene3D();
	camera = new Camera3D();

	view = new View3D();
	view.scene = scene;
	view.camera = camera;

	//setup controller to be used on the camera
	cameraController = new HoverController(camera, null, 255, 50, 300, 5);
	view.addSourceURL("srcview/index.html");
	addChild(view);

	//add signature
	Signature = Sprite(new SignatureSwf());
	SignatureBitmap = new Bitmap(new BitmapData(Signature.width, Signature.height, true, 0));
	stage.quality = StageQuality.HIGH;
	SignatureBitmap.bitmapData.draw(Signature);
	stage.quality = StageQuality.LOW;
	addChild(SignatureBitmap);

	addChild(new AwayStats(view));
}

引擎准备完后就是进入主题了,开始制作各种粒子。away3d中的生成粒子有几个步骤:

1、定义粒子需要的几何体集合,比如该教程中传送门的转动圆盘需要1个plane, 浮动的粒子需要50个plane来表现;

2、根据几何体几何,生成粒子需要的ParticleGeometry;

3、根据ParticleGeometry、Material,生成粒子mesh;

4、定义particleAnimationSet。粒子中的动作节点分为局部静态动作、局部动态动作还有全局动作,一个particleAnimationSet可以添加以上多种类型的不同动作节点;进一步了解动作细节,点击查看官方文档

5、根据particleAnimationSet定义ParticleAnimator,并把ParticleAnimator装到粒子mesh上。

6、设置粒子的start time,duration time, delay time及局部动作属性。

文字太抽象,下面是直观的代码:


		/**
		 * 初始化粒子材质
		 */
		private function initMaterials():void
		{
			matPan = new TextureMaterial(Cast.bitmapTexture(panTexture));
			matBall = new TextureMaterial(Cast.bitmapTexture(blueballTexture));
			matLight1 = new TextureMaterial(Cast.bitmapTexture(lightTexture));
			matLight2 = new TextureMaterial(Cast.bitmapTexture(lightTexture));
			matLight3 = new TextureMaterial(Cast.bitmapTexture(lightTexture));

			matPan.bothSides = true;
			matPan.smooth = true;
			matPan.repeat = true;
			matPan.alphaBlending = true;
			matPan.specularColor = 0xFF1161D9;
			matPan.ambientColor = 0xFF1161D9;

			matLight1.bothSides = true;
			matLight1.smooth = true;
			matLight1.alphaBlending = true;

			matLight2.bothSides = true;
			matLight2.smooth = true;
			matLight2.alphaBlending = true;

			matLight3.bothSides = true;
			matLight3.smooth = true;
			matLight3.alphaBlending = true;

			matBall.bothSides = true;
			matBall.repeat = true;
			matBall.smooth = true;
			matBall.alphaBlending = true;
		}

		/**
		 * 初始化粒子
		 */
		private function initParticles():void
		{
			// 设置所有粒子的particleGeometry
			var ball:Geometry = new PlaneGeometry(3,3,1,1,false);
			var light1:Geometry = new CylinderGeometry(50,30,200,16,1,false,false,true);
			var light2:Geometry = new CylinderGeometry(55,30,180,16,1,false,false,true);
			var light3:Geometry = new CylinderGeometry(60,30,160,16,1,false,false,true);
			var pan:Geometry = new PlaneGeometry(65,65,1,1);

			var ballGeoSet:Vector.<Geometry> = new Vector.<Geometry>();
			var light1GeoSet:Vector.<Geometry> = new Vector.<Geometry>();
			var light2GeoSet:Vector.<Geometry> = new Vector.<Geometry>();
			var light3GeoSet:Vector.<Geometry> = new Vector.<Geometry>();
			var panGeoSet:Vector.<Geometry> = new Vector.<Geometry>();

			// particle ball
			for (var i:int = 0; i < 40; i++) {
				ballGeoSet.push(ball);
			}
			particleGeometry1 = ParticleGeometryHelper.generateGeometry(ballGeoSet);

			particleAnimationSet1 = new ParticleAnimationSet(true, true, false);
			particleAnimationSet1.addAnimation(new ParticleBillboardNode());
			particleAnimationSet1.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,30,0)));
			particleAnimationSet1.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL,true,true,false,false,new ColorTransform(), new ColorTransform(1,1,1,0)));
			particleAnimationSet1.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.LOCAL_STATIC));
			particleAnimationSet1.addAnimation(new ParticleOscillatorNode(ParticlePropertiesMode.LOCAL_STATIC));
			particleAnimationSet1.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.LOCAL_STATIC));
			particleAnimationSet1.initParticleFunc = initBallParticleProperties;

			// light 1
			light1GeoSet.push(light1);
			particleGeometry2 = ParticleGeometryHelper.generateGeometry(light1GeoSet);
			particleAnimationSet2 = new ParticleAnimationSet(true, true, false);
			particleAnimationSet2.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,100,0)));
			particleAnimationSet2.addAnimation(new ParticleRotationalVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,1,0,25)));
			particleAnimationSet2.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL,true,true,false, false,new ColorTransform(1,1,1,0.2), new ColorTransform(1,1,1,0.2)));
			particleAnimationSet2.initParticleFunc = initLightParticleProperties;

			// light 2
			light2GeoSet.push(light2);
			particleGeometry3 = ParticleGeometryHelper.generateGeometry(light2GeoSet);
			particleAnimationSet3 = new ParticleAnimationSet(true, true, false);
			particleAnimationSet3.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,90,0)));
			particleAnimationSet3.addAnimation(new ParticleRotationalVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,1,0,25)));
			particleAnimationSet3.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL,true,true,false, false,new ColorTransform(1,1,1,0.2), new ColorTransform(1,1,1,0.2)));
			particleAnimationSet3.initParticleFunc = initLightParticleProperties;

			// light 3
			light3GeoSet.push(light3);
			particleGeometry4 = ParticleGeometryHelper.generateGeometry(light3GeoSet);
			particleAnimationSet4 = new ParticleAnimationSet(true, true, false);
			particleAnimationSet4.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,90,0)));
			particleAnimationSet4.addAnimation(new ParticleRotationalVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,1,0,25)));
			particleAnimationSet4.addAnimation(new ParticleColorNode(ParticlePropertiesMode.GLOBAL,true,true,false, false,new ColorTransform(1,1,1,0.2), new ColorTransform(1,1,1,0.2)));
			particleAnimationSet4.initParticleFunc = initLightParticleProperties;

			// pan
			panGeoSet.push(pan);
			particleGeometry5 = ParticleGeometryHelper.generateGeometry(panGeoSet);
			particleAnimationSet5 = new ParticleAnimationSet(true, true, false);
			particleAnimationSet5.addAnimation(new ParticleRotationalVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0,1,0,8)));
			particleAnimationSet5.initParticleFunc = initPanParticleProperties;

		}

		/**
		 * 初始化场景
		 */
		private function initObjects():void
		{
			particleMesh1 = new Mesh(particleGeometry1, matBall);
			particleMesh2 = new Mesh(particleGeometry2, matLight1);
			particleMesh3 = new Mesh(particleGeometry3, matLight2);
			particleMesh4 = new Mesh(particleGeometry4, matLight3);
			particleMesh5 = new Mesh(particleGeometry5, matPan);
			scene.addChild(particleMesh1);
			scene.addChild(particleMesh2);
			scene.addChild(particleMesh3);
			scene.addChild(particleMesh4);
			scene.addChild(particleMesh5);

			animator1 = new ParticleAnimator(particleAnimationSet1);
			animator2 = new ParticleAnimator(particleAnimationSet2);
			animator3 = new ParticleAnimator(particleAnimationSet3);
			animator4 = new ParticleAnimator(particleAnimationSet4);
			animator5 = new ParticleAnimator(particleAnimationSet5);

			particleMesh1.animator = animator1;
			particleMesh2.animator = animator2;
			particleMesh3.animator = animator3;
			particleMesh4.animator = animator4;
			particleMesh5.animator = animator5;

			animator1.start();
			animator2.start();
			animator3.start();
			animator4.start();
			animator5.start();
		}

		/**
		 * 初始化浮动粒子属性
		 */
		private function initBallParticleProperties(properties:ParticleProperties):void
		{
			properties.startTime = Math.random()*4.1;
			properties.duration = 3;
			var degree1:Number = Math.random() * Math.PI ;
			var degree2:Number = Math.random() * Math.PI;
			var r1:Number = Math.random()*15;
			var r2:Number = Math.random()*20 +10;
			properties[ParticlePositionNode.POSITION_VECTOR3D] = new Vector3D(r1*Math.sin(degree1), 0 , r1*Math.cos(degree1));
			properties[ParticleOscillatorNode.OSCILLATOR_VECTOR3D] = new Vector3D(r2*Math.sin(degree2), 0 , r2*Math.cos(degree2), Math.random()*4+2);
			properties[ParticleVelocityNode.VELOCITY_VECTOR3D] =  new Vector3D(0,Math.random()*100,0);
		}

		/**
		 * 初始化光辉属性
		 */
		private function initLightParticleProperties(properties:ParticleProperties):void
		{
			properties.startTime = 1;
			properties.duration = 10;
		}

		/**
		 * 初始化符文转盘属性
		 */
		private function initPanParticleProperties(properties:ParticleProperties):void
		{
			properties.startTime = 1;
			properties.duration = 1;
		}

猛击下载源码

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>