智慧 + 毅力 = 无所不能

正确性、健壮性、可靠性、效率、易用性、可读性、可复用性、兼容性、可移植性...

导航

cool down 效果更新,优化CPU

Posted on 2010-06-01 11:45  Bill Yuan  阅读(877)  评论(0编辑  收藏  举报

 转自:http://www.lite3.cn/blog/?p=510

 

代码
package cn.lite3.display 
{
    
import flash.display.Bitmap;
    
import flash.display.BitmapData;
    
import flash.display.DisplayObject;
    
import flash.display.Shape;
    
import flash.display.Sprite;
    
import flash.events.Event;
    
import flash.geom.ColorTransform;
    
import flash.geom.Point;
    
import flash.geom.Rectangle;
    
import flash.utils.getTimer;
 
    
/**
     * 在一周结束后,触发 flash.events.Event.COMPLETE 事件
     * @eventType flash.events.Event
     
*/
    [Event(name
="complete", type="flash.events.Event")]
 
    
/**
     * 一个可转动的扇形,就像游戏里的冷却时间一样<br />
     * 可以附加到任意显示对象,也不用理会目标是否缩放,注册点位置<br />
     * 只需要目标在现实列表里
     * 
     * www.lite3.cn
     * <a herf="
http://www.lite3.cn">www.lite3.cn</a>
     * 
@author lite3
     
*/
    
public class CoolDown extends Sprite
    {
        
private const startFrom:Number = -90 / 180 * Math.PI;
        
private var _running:Boolean = false;
        
private var _color:uint;
 
        
private var halfW:Number;        // 半个宽
        private var halfH:Number;        // 半个高
 
        
private var radianList:Array;    // 存放4个角的弧度
        private var pointXList:Array;    // 存放4个角的X坐标
        private var pointYList:Array;    // 存放4个角的Y坐标
 
        
private var beginTime:Number;    // 开始的时间
        private var totalTime:Number;    // 总时间
 
        
private var maskShape:Shape;
        
private var bitmap:Bitmap;
 
        
public function CoolDown(display:DisplayObject) 
        {
            mouseChildren 
= false;
            mouseEnabled 
= false;
 
            
if (display) setTarget(display);
        }
 
        
/**
         * 是否在转动
         
*/
        
public function get running():Boolean { return _running; }
 
        
/**
         * 颜色 不包括 alpha通道
         
*/
        
public function get color():uint { return _color; }
        
public function set color(value:uint):void 
        {
            
if (_color != value)
            {
                _color 
= value;
                
if (bitmap)
                {
                    var r:Number 
= (value & 0xFF0000>>> 16;
                    var g:Number 
= (value & 0x00FF00>>> 8;
                    var b:Number 
= value & 0x0000FF;
                    bitmap.transform.colorTransform 
= new ColorTransform(0001, r, g, b);
                }
            }
        }
 
        
/**
         * 销毁自己,只有在不用的时候才需调用
         
*/
        
public function dispose():void
        {
            
// 清除bitmapData
            try {
                bitmap.bitmapData.dispose();
                bitmap.bitmapData 
= null;
            }
catch (e:Error) { }
 
            
if (maskShape && maskShape.hasEventListener(Event.ENTER_FRAME))
            {
                maskShape.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
                maskShape.graphics.clear();
            }
        }
 
        
/**
         * 设置目标,并添加到目标上层<br />
         * 目标必须在现实列表里<br />
         * 转动结束后出发complete事件
         * 
         * 
@param    display
         * @eventType    flash.events.Event
         
*/
        
public function setTarget(display:DisplayObject):void
        {
            
// init UI
            if (!maskShape) maskShape = new Shape();
            addChild(maskShape);
 
            
if (!bitmap) bitmap = new Bitmap();
            
if (bitmap.bitmapData) bitmap.bitmapData.dispose();
 
            var rect:Rectangle 
= display.getBounds(display.parent);
            halfW 
= rect.width  * 0.5;
            halfH 
= rect.height * 0.5;
            pointXList 
= [-halfW, -halfW, halfW, halfW];
            pointYList 
= [-halfH, halfH, halfH, -halfH];
            radianList 
= 
                [ Math.atan2(
-halfH, -halfW) + Math.PI * 2,
                  Math.atan2( halfH, 
-halfW),
                  Math.atan2( halfH, halfW),
                  Math.atan2( 
-halfH, halfW),
                  startFrom ];
 
            var bitmapData:BitmapData 
= new BitmapData(rect.width, rect.height, true0x0);
            var stageP:Point 
= display.parent.localToGlobal(new Point(rect.x, rect.y));
 
            bitmapData.lock();
            
for (var i:int = 0; i < rect.width; i++)
            {
                
for (var j:int = 0; j < rect.height; j++)
                {
                    
if (display.hitTestPoint(stageP.x + i, stageP.y + j, true))
                        bitmapData.setPixel32(i, j, 
0xFF000000);
                }
            }
            bitmapData.unlock();
            bitmap.bitmapData 
= bitmapData;
            bitmap.x 
= -halfW;
            bitmap.y 
= -halfH;
            addChild(bitmap);
            bitmap.mask 
= maskShape;
 
            
this.x = rect.x + halfW;
            
this.y = rect.y + halfH;
            
// 添加到显示列表
            display.parent.addChildAt(this, display.parent.getChildIndex(display) + 1);
        }
 
        
/**
         * 从某个角度开始转一周
         * 
@param    starFrom    开始转动的角度
         * 
@param    totalTime    转一圈所用的时间(单位:毫秒)
         
*/
        
public function start(totalTime:Number):void
        {
            
if (maskShape)
            {
                
this.totalTime = totalTime;
                beginTime 
= getTimer();
                _running 
= true;
 
                
// 先画一个矩形
                maskShape.graphics.beginFill(0);
                maskShape.graphics.drawRect( 
-halfW, -halfW, halfW * 2, halfH * 2);
                maskShape.graphics.endFill();
 
                
if (!maskShape.hasEventListener(Event.ENTER_FRAME))
                    maskShape.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
            }
        }
 
        
private function enterFrameHandler(e:Event):void 
        {
            var postTime:Number 
= getTimer() - beginTime;
            maskShape.graphics.clear();
 
            
// 时间到了
            if (postTime >= totalTime)
            {
                maskShape.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
                _running 
= false;
                dispatchEvent(
new Event(Event.COMPLETE));
            }
            
// 时间还没到
            else
            {
                maskShape.graphics.beginFill(
0);
                maskShape.graphics.lineTo(
0-halfH);
                var currRadian:Number 
= 2 * Math.PI * (postTime / totalTime) + startFrom;
                var px:Number, py:Number;
                
for (var i:int = 0; i < 5; i++)
                {
                    var radian:Number 
= radianList[i];
                    
if (currRadian < radian)
                    {
                        maskShape.graphics.lineTo(pointXList[i], pointYList[i]);
                    }
else
                    {
                        
if (1 == i || 3 == i)
                        {
                            px 
= 1 == i ? -halfW : halfW;
                            py 
= Math.tan(currRadian) * px;
                        }
else
                        {
                            py 
= 2 == i ? halfH : -halfH;
                            px 
= py / Math.tan(currRadian);
                        }
                        maskShape.graphics.lineTo(px, py);
                        
break;
                    }
                }
                maskShape.graphics.lineTo(
00);
                maskShape.graphics.endFill();
            }
        }
    }
}