冷却时间(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();
            }
        }
    }
}

完整示例源码下载☞

标签: ,

  1. lite3 | | #1

    @老鱼
    如果要盖住的显示对象是矩形的话,就删除bitmap相关的代码,这样效率还能更高些。
    如果要盖住的显示对象不是矩形(比如这个示例中有圆弧边),那么就需要bitmap。
    这个bitmap是作为要盖住对象的形状副本的,再配合mask就可以实现任意形状cd的效果了。

  2. 老鱼 | #2

    把代码嵌入,按照例子调用之后没有效果,调试过程中把bitmap.mask = maskShape;注释之后,效果就出来了,再调整一下透明度就是我想要的效果了。于是把bitmap相关的也注释掉,效果依旧,想知道bitmap在里面的作用什么?不用反正有效果。

  3. sky | #3

    @lite3
    谢谢博主,目前把实例化放在技能点击事件里,一切正常

  4. lite3 | | #4

    @sky
    外部加载一般跟stage有关, 看看有没有侦听Event.addToStage事件

  5. sky | #5

    为什么我在外部加载用到这个冷却效果的swf时 冷却的效果就显示不了了呢。?

  6. lite3 | | #6

    @Cool forex technical analysis free tools
    谢谢,欢迎使用,哈哈

  7. Cool forex technical analysis free tools | #7

    确实很不错我可能下载。谢谢

  8. jack_ni | #8

    :shock:

  9. lite3 | | #9

    @迷
    O(∩_∩)O~, 还好了,一直不更新就没人来了,放几个小东东,好吸引大家来光顾啊 :roll:
    是的啊,第一次写了名字 邮箱 ,第二次就不用再写了

  10. | #10

    :oops: 第二次不用了吗

  11. | #11

    三哥文化人呀,会搞小发明小研究,俺是粗人呢 :o

  1. 本文目前尚无任何 trackbacks 和 pingbacks.
回到顶部