非常抱歉,这个只想到效果,忘记了CPU,我又重新写了个,请看 冷却时间(CD,cool down) 效果更新,优化CPU
左边是一个冷却时间效果,右边是一个扇形
这是一个冷却效果cd的演示demo,如果你看不到这个flash,请到文章页面查看!
这里是一个游戏里常用到的冷却时间效果。
先是在 这里 看到 wizim 写的这个效果没有完工,又看到有好多人回帖说想要这样的效果,然后我就把它写成类,写的更通用些。
可以附加到任意显示对象上,只需目标显示对象在显示列表里。
当然,要是flex里用,则需继承UIComponent。
废话就不多说了,直接上代码。
Sector 这是一个扇形类:
package com.litefeel.display
{
import flash.display.Sprite;
/**
* 一个扇形类
*
* www.litefeel.com
* @author lite3
*/ public class Sector extends Sprite
{
private var _radius:Number;
private var _angle:Number;
private var _startFrom:Number;
private var _fullColor:uint;
private var _lineColor:uint;
private var _lineThickness:Number;
private var _showTieLine:Boolean;
public function get showTieLine():Boolean { return _showTieLine; }
public function get lineColor():uint { return _lineColor; }
public function get lineThickness():uint { return _lineThickness; }
public function get fullColor():uint { return _fullColor; }
public function get startFrom():Number { return _startFrom; }
public function get angle():Number { return _angle; }
public function get radius():Number { return _radius; }
/**
* 实例化一个扇形
* @param radius
* @param angle
* @param startFrom
* @param fullColor
* @param lineColor
* @param lineThickness
* @param showTieLine
*/ public function Sector(radius:Number, angle:Number, startFrom:Number = 270,
fullColor:uint = 0xFF00FFFF, lineColor:uint = 0xFF000000,
lineThickness:Number = 1, showTieLine:Boolean = true)
{
drawSector(radius, angle, startFrom, fullColor, lineColor,lineThickness, showTieLine);
}
/**
* 画扇形
* @param radius 半径
* @param angle 扇形的角度 >= 0 , if > 360 ,则 = 360
* @param startFrom 开始角度 无效值则为0
* @param fullColor 填充颜色 ARGB 格式的
* @param lineColor 线条颜色 ARGB 格式的
* @param showTieLine 是否显示原点到弧线的连线
*/ public function drawSector(radius:Number, angle:Number, startFrom:Number = 270,
fullColor:uint = 0xFF00FFFF, lineColor:uint = 0xFF000000,
lineThickness:Number = 1, showTieLine:Boolean = true):void
{
if (isNaN(radius) || radius < 0) radius = 0;
if (isNaN(angle) || angle < 0) angle = 0;
if (angle > 360) angle = 360;
if (isNaN(startFrom)) startFrom = 0;
_radius = radius;
_angle = angle;
_startFrom = startFrom;
_fullColor = fullColor;
_lineColor = lineColor;
_lineThickness = lineThickness;
_showTieLine = showTieLine;
// 清除以前的
graphics.clear();
if (angle >> 24) / 0xFF);
graphics.beginFill(fullColor & 0xFFFFFF, (fullColor >>> 24) / 0xFF);
var radian:Number = startFrom / 180 * Math.PI; // 弧度,临时替换用的
var px:Number = Math.cos(radian) * radius; // 划线的坐标点
var py:Number = Math.sin(radian) * radius;
graphics.lineTo(px, py);
if (!showTieLine) graphics.lineStyle(lineThickness, lineColor & 0xFFFFFF, (lineColor >>> 24) / 0xFF);
// 画圆弧
while (angle > 0)
{
var tempAngle:Number = (angle >= 45) ? 45 : angle;
// 控制点坐标
radian = (startFrom + tempAngle * 0.5) / 180 * Math.PI;
var cx:Number = radius / Math.cos(tempAngle / 360 * Math.PI) * Math.cos(radian);
var cy:Number = radius / Math.cos(tempAngle / 360 * Math.PI) * Math.sin(radian);
// 更新角度
startFrom += tempAngle;
angle -= tempAngle;
// 计算划线末点坐标
radian = startFrom / 180 * Math.PI;
px = Math.cos(radian) * radius;
py = Math.sin(radian) * radius;
// 画线
graphics.curveTo(cx, cy, px, py);
}
// 连接到结束点
if (!showTieLine) graphics.lineStyle(0, 0, 0);
graphics.lineTo(0, 0);
graphics.endFill();
}
}
}
MovableSector 这是实现冷却时间效果的类:
package com.litefeel.display
{
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 事件
*/ [Event(name="complete", type="flash.events.Event")]
/**
* 一个可转动的扇形,就像游戏里的冷却时间一样
* 可以附加到任意显示对象,也不用理会目标是否缩放,注册点位置
* 只需要目标在现实列表里
*
* www.litefeel.com
* @author lite3
*/ public class MovableSector extends Sprite
{
private var _running:Boolean = false;
private var _color:uint;
private var beginTime:Number; // 开始的时间
private var totalTime:Number; // 总时间
private var startFrom:Number; // 开始的角度
private var sector:Sector;
private var maskShape:Shape;
public function MovableSector(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 (maskShape)
{
var r:Number = (value & 0xFF0000) >>> 16;
var g:Number = (value & 0x00FF00) >>> 8;
var b:Number = value & 0x0000FF;
trace(r, g, b);
maskShape.transform.colorTransform = new ColorTransform(0, 0, 0, 1, r, g, b);
}
}
}
/**
* 设置目标,并添加到目标上层
* 目标必须在现实列表里
* 转动结束后出发complete事件
*
* @param display
* @eventType flash.events.Event
*/ public function setTarget(display:DisplayObject):void
{
// init UI
if (sector) removeChild(sector);
if (!maskShape) maskShape = new Shape();
var radius:Number = Math.sqrt(display.width * display.width + display.height * display.height) * 0.5;
sector = new Sector(radius, 0, -90, 0xFFFFFFFF, 0, 0, false);
addChild(sector);
var rect:Rectangle = display.getBounds(display.parent);
var stageP:Point = display.localToGlobal(new Point(rect.x, rect.y));
var halfW:Number = rect.width * 0.5;
var halfH:Number = rect.height * 0.5;
maskShape.graphics.clear();
maskShape.graphics.beginFill(_color);
for (var i:int = 0; i < rect.width; i++)
{
for (var j:int = 0; j < rect.height; j++)
{
if (display.hitTestPoint(rect.x + i, rect.y + j, true))
maskShape.graphics.drawRect(i - halfW, j - halfH, 1, 1);
}
}
addChild(maskShape);
maskShape.cacheAsBitmap = true;
maskShape.mask = sector;
this.x = rect.x + halfW;
this.y = rect.y + halfH;
// 添加到显示列表
display.parent.addChildAt(this, display.parent.getChildIndex(display) + 1);
}
/**
* 从某个角度开始转一周
* @param startFrom 开始转动的角度
* @param totalTime 转一圈所用的时间(单位:毫秒)
*/ public function start(startFrom:Number, totalTime:Number):void
{
if (sector)
{
this.startFrom = startFrom;
this.totalTime = totalTime;
beginTime = getTimer();
_running = true;
// 先画一个圆
sector.drawSector(sector.radius, 360, startFrom, 0xCC000000, 0x00000000, 0, false);
if (!sector.hasEventListener(Event.ENTER_FRAME))
sector.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
}
private function enterFrameHandler(e:Event):void
{
var postTime:Number = getTimer() - beginTime;
// 时间到了
if (postTime >= totalTime)
{
sector.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
sector.drawSector(sector.radius, 0);
_running = false;
dispatchEvent(new Event(Event.COMPLETE));
}
// 时间还没到
else
{
var postAngle:Number = 360 * postTime / totalTime;
sector.drawSector(sector.radius, 360 - postAngle, startFrom + postAngle, 0x0, 0x0, 0, false);
}
}
}
}
» 转载请注明来源:www.litefeel.com » 《游戏里冷却时间效果 cool down (CD) 扇形》
» 本文链接地址:https://www.litefeel.com/cooldown-effect/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
» 本文链接地址:https://www.litefeel.com/cooldown-effect/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
This post was last modified on 2019 年 03 月 04 日 01:07
View Comments (3)
@foxlively
O(∩_∩)O~,这个倒是忘记了,没注意CPU,想到好方法了再改 :grin:
效果好
但CPU占用率太高了
WOW里应该不是用这种原理实现的吧,否则全都是这个cooldown机器死定了
哈哈 不错