/*重绘(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(); } } }