我一直在寻找一个示例代码来创建一个简单的倒数计时器。
它会以“小时:分钟:秒”显示时间,我可以将时间设置为10分钟,30分钟,1小时,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 );
}
使用getTimer
(get 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 );
}