冷却时间(CD,cool down) 效果更新,优化CPU
转动一周结束后点击可重新开始。
这是一个冷却效果cd的演示demo,如果你看不到这个flash,请到文章页面查看!
非常抱歉,只是想着实现效果,没留意CPU,竟然那么高,然后又想了一个简单的办法,可是没放游戏里测试过,所以不知道是否可以实际应用。
现在用bitmap做底,所以添加了 dispose 方法。start方法去掉了开始角度。
好了,废话不多说了,直接看代码。
CoolDown cool down 效果的类:
package com.litefeel.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.litefeel.com
* <a herf="http://www.litefeel.com">www.litefeel.com</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();
}
}
}
}
» 转载请注明来源:www.litefeel.com » 《冷却时间(CD,cool down) 效果更新,优化CPU》
» 本文链接地址:https://www.litefeel.com/cooldown-effect-optimization/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
» 本文链接地址:https://www.litefeel.com/cooldown-effect-optimization/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
@老鱼
如果要盖住的显示对象是矩形的话,就删除bitmap相关的代码,这样效率还能更高些。
如果要盖住的显示对象不是矩形(比如这个示例中有圆弧边),那么就需要bitmap。
这个bitmap是作为要盖住对象的形状副本的,再配合mask就可以实现任意形状cd的效果了。
把代码嵌入,按照例子调用之后没有效果,调试过程中把bitmap.mask = maskShape;注释之后,效果就出来了,再调整一下透明度就是我想要的效果了。于是把bitmap相关的也注释掉,效果依旧,想知道bitmap在里面的作用什么?不用反正有效果。
@lite3
谢谢博主,目前把实例化放在技能点击事件里,一切正常
@sky
外部加载一般跟stage有关, 看看有没有侦听Event.addToStage事件
为什么我在外部加载用到这个冷却效果的swf时 冷却的效果就显示不了了呢。?
@Cool forex technical analysis free tools
谢谢,欢迎使用,哈哈
确实很不错我可能下载。谢谢
:shock:
@迷
O(∩_∩)O~, 还好了,一直不更新就没人来了,放几个小东东,好吸引大家来光顾啊 :roll:
是的啊,第一次写了名字 邮箱 ,第二次就不用再写了
:oops: 第二次不用了吗
三哥文化人呀,会搞小发明小研究,俺是粗人呢 :o