转自: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(0, 0, 0, 1, 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, true, 0x0);
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(0, 0);
maskShape.graphics.endFill();
}
}
}
}
{
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(0, 0, 0, 1, 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, true, 0x0);
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(0, 0);
maskShape.graphics.endFill();
}
}
}
}