重绘 贝赛尔曲线特效

/*重绘(redraw)的定义:Flash Player 会以SWF内容的帧频速度来刷新需要变化的内容,而这个刷新的过程,我们通常称为“重绘(redraw)”.

【重绘是Flash Player性能消耗的主要根源】 

发生重绘的情况:

①舞台上的可视组件的形状、位置、状态(alpha, scale…)等发生改变.

②当一个DisplayObject的层级(ChildIndex)发生改变.

③Sprite / MovieClip 的buttonMode 设置为 true ,重绘会在MouseEvent.MOUSE_DOWN的时候触发.



如何减少重绘:

①带有动画效果的DisplayObject在不显示时,暂停该DisplayObject,或者利用removeChild(displayObject) 直接将此对象移除出显示列表.

②将DisplayObject对象转移到FlashPlayer的不可视范围里,FlashPlayer将不对其进行重绘,这里的不可视范围除了舞台以外,还包括被其他物体遮盖住的显示对象.

③在设置DisplayObject的层级的时候请先做一个判断:

if(myContainer.getChildIndex(myChild) != 0)

{

	myContainer.setChildIndex(myChild, 0);

}

④当你的Sprite / MovieClip 设置 cacheAsBitmap = true 这个属性的时候,当此显示对象内很小的一个区域(甚至是被遮盖着的物体)发生变化,

会导致整个Sprite / MovieClip重绘,当 cacheAsBitmap = true 遇上 scrollRect 属性,也可减小重绘区域.



如何强制重绘:

①使用updateAfterEvent()方法.

引用YouYee的一句话:重绘是Flash Player性能消耗的主要大户,所以去优化减小重绘区域面积,减少不必要的重绘操作次数,往往能够带来比较大的性能优化回报



Any More:

单纯的理论可能难以让人理解,下面是我写的一个贝塞尔曲线的例子:

在这个例子中,如果你的FP版本是Debug版本的话,你右击鼠标点”显示重绘区域“,就会发现重绘的改变过程是有多么的美妙和奇妙,当舞台放大时,你会发现旋转变慢了CPU资源占用变大了,

而当舞台变小时,你就会发现旋转变快了CPU资源占用变小了(测试环境,本地FP播放,手动拉伸FP播放器,前提是设置舞台的StageScaleMode为EXACT_FIT)…



下面是这个程序例子的关键代码*/



package 

{

	import flash.display.Sprite;

	import flash.events.*;

	import flash.filters.GlowFilter;

	import flash.geom.Point;

	import flash.utils.Timer;



	public class BezierCurve extends Sprite

	{

		/* 属性 */

		// 定义半径

		private var _radius:int = 70;

		// 定义点的数量

		private var _numberPoint:Number = 30;

		private var _points:Array;

		private var _pre_r:Number = 0.000314159;

		private var _radians:Number = 0;

		// X坐标的位置

		private var _centX:Number;

		// Y坐标的位置

		private var _centY:Number;

		// 创建刷新用的计时器

		private var _timer:Timer;

		// 对象的颜色

		private var _color:uint;

		// 使对象产生发光效果

		private var _gf:GlowFilter;

		private var _loc_1:int;

		private var _loc_2:Point;



		/* 构造函数*/

		public function BezierCurve(_x:Number, _y:Number)

		{

			super();

			//在此初始化数值

			// 初始化【颜色】

			_color = 0x3377dd;

			// 初始化【X】坐标

			_centX = _x;

			// 初始化【Y】坐标

			_centY = _y;

			// 初始化【发光效果】,颜色为0x00ffff

			_gf=new GlowFilter();

			// 初始化【水平】模糊量

			_gf.blurX = _loc_1;

			// 初始化【垂直】模糊量

			_gf.blurY = 32;

			// 初始化【光晕颜色】

			_gf.color = _color;

			// 着色器

			filters = [_gf];

			// 初始化一个数组,用以

			_points=new Array();

			/* 以下为 —— 启动刷新计时器 */

			// 启动计时器

			this.addEventListener(Event.ENTER_FRAME,_onEnterFrame);

			/* —— 结束计时器 */

		}



		/* 方法 */

		private function _onEnterFrame(e:Event):void

		{

			// 刷新后的动作

			// trace(“成功执行Timer”);

			run();//进行一个run动作



		}



		private function run():void

		{

			// 清除绘制到此 Graphics 对象的图形,并重置填充和线条样式设置

			this.graphics.clear();

			_points = [];

			_radians = _radians + _pre_r;

			_loc_1 = 0;// 设置水平模糊变量

			// ——————————————- Begin While ——————————————-

			while (_loc_1 < _numberPoint)

			{

				// 每执行一次while都新建一个Point数组

				_loc_2 = new Point();

				_loc_2.x = _centX + Math.cos(_radians * _loc_1) * 140;

				_loc_2.y = _centY + Math.sin(_radians * _loc_1) * 140;

				// 将一个或多个元素添加到数组的结尾,并返回该数组的新长度

				_points.push(_loc_2);

				_loc_1 +=  1;

			}

			// ------------------------------------------- End While -------------------------------------------

			this.graphics.beginFill(_color, 0.2);

			// 设定线条颜色;

			this.graphics.lineStyle(1, _color , 0.8);

			// 移动;

			this.graphics.moveTo(_centX, _centY);

			_loc_1 = 2;

			while (_loc_1 < _numberPoint - 2 )

			{

				this.graphics.curveTo(_points[_loc_1 - 1].x, _points[_loc_1 - 1].y, _points[_loc_1].x, _points[_loc_1].y);

				this.graphics.curveTo(_points[_loc_1 + 1].x, _points[_loc_1 + 1].y, _centX, _centY);

				_loc_1 +=  1;

			}

			//绘制贝塞尔曲线

			this.graphics.endFill();

		}

	}

}

你可能感兴趣的:(特效)