AS3带闹钟的简易定时器?

时间:2012-12-11 23:37:44

标签: actionscript-3 air

我一直在寻找一个示例代码来创建一个简单的倒数计时器。

它会以“小时:分钟:秒”显示时间,我可以将时间设置为10分钟,30分钟,1小时,2小时等。

当计时器达到零时,它将执行一项功能。非常感谢您的帮助。我在网上找到的唯一东西是倒数到特定的日期。

2 个答案:

答案 0 :(得分:1)

制作计时器非常简单。您可以在AS3定时器类上阅读更多内容。将时间显示为HH:MM:SS是一点工作。我需要这样做时使用这个类:

package com.dop.utils
{
    public class Timecodes
    {
        public function Timecodes()
        {
        }

        public static function timecodeToSeconds(tcStr:String):Number
        {
            var t:Array = tcStr.split(":");
            return (t[0] * 3600 + t[1] * 60 + t[2] * 1);
        }

        public static function secondsToTimecode(seconds:Number):String
        {
            var minutes:Number          = Math.floor(seconds/60);
            var remainingSec:Number     = seconds % 60;
            var remainingMinutes:Number = minutes % 60;
            var hours:Number            = Math.floor(minutes/60);
            var floatSeconds:Number     = Math.floor((remainingSec - Math.floor(remainingSec))*100);
            remainingSec                = Math.floor(remainingSec);

            return getTwoDigits(hours) + ":" + getTwoDigits(remainingMinutes) + ":" + getTwoDigits(remainingSec);
        }

        private static function getTwoDigits(number:Number):String
        {
            if (number < 10)
            {
                return "0" + number;
            }
            else
            {
                return number + "";
            }
        }
    }
}

我做了一个小例子,你可以在这里看到这个类:http://ronnieswietek.com/cc/alarm/alarm.swf

(来源:http://ronnieswietek.com/cc/alarm/alarm.fla

我使用Timer类的代码在这里:

import com.dop.utils.Timecodes;
import flash.events.*;
import fl.controls.*;
import fl.data.*;
import flash.utils.Timer;

var timer:Timer = new Timer(1000); //-- run once a second
timer.addEventListener(TimerEvent.TIMER, onTimer);

var countdown:Number = 0;
var durations:Array = [
    {label:'1 minute',time:1},
    {label:'5 minutes',time:5},
    {label:'10 minutes',time:10},
    {label:'30 minutes',time:30},
    {label:'1 hour',time:60},
    {label:'2 hours',time:120},
    {label:'3 hours',time:180}
];

durationBox.dataProvider = new DataProvider(durations);
timerButton.addEventListener(MouseEvent.CLICK, timerHandler);

function timerHandler(e:MouseEvent):void
{
    if (!timer.running)
    {
        var selectedTime:Number = durationBox.selectedItem.time * 60;
        countdown = selectedTime;
        timeText.text = Timecodes.secondsToTimecode(countdown);
        timer.start();
        timerButton.label = "Stop";
    }
    else
    {
        countdown = 0;
        timeText.text = Timecodes.secondsToTimecode(countdown);
        timer.stop();
        timer.reset();
        timerButton.label = "Start";
    }
}

function onTimer(e:TimerEvent):void
{
    timeText.text = Timecodes.secondsToTimecode(countdown);
    countdown--;
    if (countdown == 0)
    {
        timer.stop();
        timer.reset();
        timeText.text = "ALARM!!!";
    }
}

答案 1 :(得分:1)

如果要求准确性,您不能单独依靠Timer类来为您提供精确的时间段。特别是如果Flash Player正在做很多其他工作。这是因为Timer类间隔实际上是一个请求而不是保证。让我们来看看,从一个微不足道的实现计时器开始每秒钟滴答一次(1000毫秒):

private var startTime:uint;
private var ticks:int;

protected function start():void
{
    var t:Timer = new Timer( 1000 );
    t.addEventListener( TimerEvent.TIMER, timerTick );
    t.start();
    startTime = getTimer();
}

protected function timerTick( event:TimerEvent ):void
{
    trace( 'Ideal: ' + (++ticks) + ' Actual: ' + (getTimer()-startTime)/1000 );
}

使用getTimerget familiar with getTimer)来衡量我们在20秒内可以看到的实际时间,Timer类落后半秒。每次运行时,这种漂移都会有所不同:

Expected: 1 Actual: 1.043
Expected: 2 Actual: 2.083
Expected: 3 Actual: 3.082
…
Expected: 18 Actual: 18.417
Expected: 19 Actual: 19.457
Expected: 20 Actual: 20.5

实施秒表的目的在于更精确地测量时间:

import flash.utils.getTimer;

public class Stopwatch
{
    private var startStamp:Number;
    private var stopStamp:Number;
    private var runTime:Number;

    private var _countdownDuration:Number;

    private var started:Boolean;
    private var stopped:Boolean;
    private var paused:Boolean;

    function Stopwatch( startNow:Boolean = true ):void
    {
        if ( startNow ) 
            start();
    }

    public function start():void
    {
        runTime = 0;
        startStamp = getTimer();
        _countdownDuration = 0;
        started = true;
        stopped = false;
        paused = false;
    }

    public function startCountdown( milliseconds:Number ):void
    {
        start();
        _countdownDuration = milliseconds;
    }

    public function pause():void
    {
        if ( started && ! stopped )
        {
            runTime += getTimer() - startStamp;
            paused = true;
        }
    }

    public function resume():void
    {
        if ( started && paused )
        {
            startStamp = getTimer();
            paused = false;
        }
    }

    public function stop():void
    {
        if ( started && ! stopped )
        {
            if ( ! paused )
                runTime += getTimer() - startStamp;

            stopped = true;
            paused = false;
        }
    }

    public function set elapsed( value:uint ):void
    {
        runTime = value;

        if ( running )
            startStamp = getTimer();
    }

    public function get elapsed():uint
    {
        if ( running )
            return ( getTimer() - startStamp ) + runTime;

        return runTime;
    }

    public function get running():Boolean
    {
        return ( started && ! paused && ! stopped );
    }

    public function get countdownDuration():Number
    {
        return _countdownDuration;
    }

    public function set countdownDuration( value:Number ):void
    {
        _countdownDuration = value;
    }

    public function get remaining():int
    {
        if ( ! _countdownDuration )
            return 0;
        else if ( _countdownDuration - elapsed < 0 )
            return 0;

        return _countdownDuration - elapsed;
    }
}

使用秒表扩展第一个示例,您可以非常简单地有效地测量时间的流逝(只需记住stopwatch.elapsed以毫秒为单位,因此我们将除以1000秒):

private var stopwatch:Stopwatch;

protected function start():void
{
    var t:Timer = new Timer( 1000 );
    t.addEventListener( TimerEvent.TIMER, timerTick );
    t.start();
    stopwatch = new Stopwatch;
    stopwatch.start();
}

protected function timerTick( event:TimerEvent ):void
{
    trace( stopwatch.elapsed/1000 + ' seconds have elapsed',
           (60 * 10) - stopwatch.elapsed/1000 + ' seconds remain' );
}

由于stopwatch.elapsed以毫秒为单位,因此您需要将该数量转换为不同的时间增量。遵循单一责任原则,我们将创建一个名为StopwatchFormatter的可重用通用类,以帮助我们整合这些计算并公开可读的API:

public class StopwatchFormatter
{
    private var elapsed:Number;
    public var paddedSize:int;
    public var cappedDecimalLength:int;

    function StopwatchFormatter( paddedSize:Number = 2, cappedDecimalLength:Number = 1,  elapsed:Number = 0 )
    {
        this.elapsed = elapsed;
        this.paddedSize = paddedSize;
        this.cappedDecimalLength = cappedDecimalLength;
    }

    //  INPUTS

    public function setTimeAsGroup( hours:Number, minutes:Number = 0, seconds:Number = 0, milliseconds:Number = 0 ):StopwatchFormatter
    {
        elapsed = ( hours * 60 * 60 * 1000 ) + ( minutes * 60 * 1000 ) + ( seconds * 1000 ) + milliseconds;

        return this;
    }

    public function set totalMilliseconds( value:Number ):void
    {
        elapsed = value;
    }

    public function set totalSeconds( value:Number ):void
    {
        elapsed = value * 1000;
    }

    public function set totalMinutes( value:Number ):void
    {
        elapsed = value * 1000 * 60;
    }

    public function set totalHours( value:Number ):void
    {
        elapsed = value * 1000 * 60 * 60;
    }

    //  CLOCK LIKE 
    //  (converting to int will drop the decimal place) 

    public function get milliseconds():int
    {
        return elapsed % 1000;
    }

    public function get seconds():int
    {
        return ( elapsed / 1000 ) % 60;
    }

    public function get minutes():int
    {
        return ( elapsed / 1000 / 60 ) % 60;
    }

    public function get hours():int
    {
        return ( elapsed / 1000 / 60 / 60 ) % 24;
    }

    // CLOCK PADDED (zeroes in the front) 
    // 5 becomes "05" , 10 becomes "10" where _paddedSize is 2

    public function get millisecondsPadded():String
    {
        return frontPad( milliseconds );
    }

    public function get secondsPadded():String
    {
        return frontPad( seconds );
    }

    public function get minutesPadded():String
    {
        return frontPad( minutes );
    }

    public function get hoursPadded():String
    {
        return frontPad( hours );
    }

    // TOTAL

    public function get totalMilliseconds():Number
    { 
        return elapsed;
    }

    public function get totalSeconds():Number
    {
        return elapsed  / 1000;
    }

    public function get totalMinutes():Number
    {
        return elapsed / 1000 / 60;
    }

    public function get totalHours():Number
    {
        return elapsed / 1000 / 60 / 60;
    }

    //  TOTAL CAPPED
    //  3.134 becomes 3.1 where _cappedDecimalLength is 1

    public function get totalMillisecondsCapped():Number
    {
        return capped( totalMilliseconds );
    }

    public function get totalSecondsCapped():Number
    {
        return capped( totalSeconds );
    }

    public function get totalMinutesCapped():Number
    {
        return capped( totalMinutes );
    }

    public function get totalHoursCapped():Number
    {
        return capped( totalHours );
    }

    // TOTAL CAPPED + PADDED (zeroes in the back and one zero in the front for values less than 0)
    //  3.101 becomes "3.10" where _cappedDecimalLength is 2

    public function get totalSecondsCappedPadded():String
    {
        return capped( totalSeconds ).toFixed( cappedDecimalLength );
    }

    public function get totalMinutesCappedPadded():String
    {
        return capped( totalMinutes ).toFixed( cappedDecimalLength );
    }

    public function get totalHoursCappedPadded():String
    {
        return capped( totalHours ).toFixed( cappedDecimalLength );
    }

    // UTILITY FUNCTIONS

    private function frontPad( n:int ):String
    {
        var s:String = n.toString();
        if ( s.length < paddedSize )
        {
            var i:int = 0;
            var len:int = paddedSize - s.length;
            for ( ; i < len; i++ )
            {
                s = "0" + s;
            }
        }
        return s;
    }

    private function capped( input:Number ):Number
    {
        if ( cappedDecimalLength == 0 ) 
            return Math.floor( input );

        var decimalFactor:Number = Math.pow( 10, cappedDecimalLength );

        return Math.floor( input * decimalFactor ) / decimalFactor;
    }
}

将这两个类和一个计时器放在一起我们有一个简单的倒计时方法:

private var stopwatch:Stopwatch;
private var time:StopwatchFormatter;

protected function start():void
{
    var t:Timer = new Timer( 1000 );
    t.addEventListener( TimerEvent.TIMER, timerTick );
    t.start();
    stopwatch = new Stopwatch;
    stopwatch.startCountdown( new StopwatchFormatter().setTimeAsGroup( 1, 10, 30 ).totalMilliseconds );
    time = new StopwatchFormatter;
}

protected function timerTick( event:TimerEvent ):void
{
    time.totalMilliseconds = stopwatch.elapsed;
    var elapsed:String = time.hoursPadded + ':' + time.minutesPadded + ':' + time.secondsPadded + ':' + time.millisecondsPadded;

    time.totalMilliseconds = stopwatch.remaining;
    var remainig:String = time.hoursPadded + ':' + time.minutesPadded + ':' + time.secondsPadded + ':' + time.millisecondsPadded;

    trace( 'Elapsed:', elapsed, "Remaining:", remainig ); 
}