日期和时间示例:简单模拟时钟

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

简单的模拟时钟示例说明了这两个日期和时间概念:

  • 获取当前日期和时间并提取小时、分钟和秒的值

  • 使用 Timer 设置应用程序的运行速度

    若要获取此范例的应用程序文件,请参阅 www.adobe.com/go/learn_programmingAS3samples_flash_cn。可以在 Samples/SimpleClock 文件夹中找到 SimpleClock 应用程序文件。该应用程序包含以下文件:

    文件

    说明

    SimpleClockApp.mxml

    SimpleClockApp.fla

    Flash 或 Flex 中的主应用程序文件(分别为 FLA 和 MXML)。

    com/example/programmingas3/simpleclock/SimpleClock.as

    主应用程序文件。

    com/example/programmingas3/simpleclock/AnalogClockFace.as

    根据时间绘制一个圆形的钟面以及时针、分针和秒针。

定义 SimpleClock 类

此时钟示例很简单,但是将即使很简单的应用程序也组织得十分有条理是一种很好的做法,以便您将来能够很轻松地扩展这些应用程序。为此,SimpleClock 应用程序使用 SimpleClock 类处理启动和时间保持任务,然后使用另一个名称为 AnalogClockFace 的类来实际显示该时间。

以下代码用于定义和初始化 SimpleClock 类(请注意,在 Flash 版本中,SimpleClock 扩展了 Sprite 类):

public class SimpleClock extends UIComponent 
{ 
    /** 
     * The time display component. 
     */ 
    private var face:AnalogClockFace; 
     
    /** 
     * The Timer that acts like a heartbeat for the application. 
     */ 
    private var ticker:Timer;

该类具有两个重要的属性:

  • face 属性,它是 AnalogClockFace 类的实例

  • ticker 属性,它是 Timer 类的实例

    SimpleClock 类使用默认构造函数。initClock() 方法处理实际的设置工作,它创建钟面并启动 Timer 实例的计时。

创建钟面

SimpleClock 代码中后面的几行代码创建用于显示时间的钟面:

    /** 
     * Sets up a SimpleClock instance. 
     */ 
    public function initClock(faceSize:Number = 200)  
    { 
        // creates the clock face and adds it to the display list 
        face = new AnalogClockFace(Math.max(20, faceSize)); 
        face.init(); 
        addChild(face); 
         
        // draws the initial clock display 
        face.draw();

可以将钟面的大小传递给 initClock() 方法。如果未传递 faceSize 值,则使用 200 个像素的默认大小。

接着,应用程序将钟面初始化,然后使用从 DisplayObjectContainer 类继承的 addChild() 方法将该钟面添加到显示列表。然后,它调用 AnalogClockFace.draw() 方法显示一次钟面,同时显示当前时间。

启动计时器

创建钟面后,initClock() 方法会设置一个计时器:

        // creates a Timer that fires an event once per second 
        ticker = new Timer(1000);  
     
        // designates the onTick() method to handle Timer events 
        ticker.addEventListener(TimerEvent.TIMER, onTick); 
 
        // starts the clock ticking 
        ticker.start();

首先,该方法初始化一个每秒(每隔 1000 毫秒)调度一次事件的 Timer 实例。由于没有向 Timer() 构造函数传递第二个 repeatCount 参数,因此 Timer 将无限期地重复计时。

SimpleClock.onTick() 方法将在每秒收到 timer 事件时执行一次。

    public function onTick(event:TimerEvent):void  
    { 
        // updates the clock display 
        face.draw(); 
    }

AnalogClockFace.draw() 方法仅绘制钟面和指针。

显示当前时间

AnalogClockFace 类中大多数代码都与设置钟面的显示元素有关。AnalogClockFace 在进行初始化时,会绘制一个圆形轮廓,将数字文本标签放在每个小时刻度处,然后创建三个 Shape 对象,分别表示时钟的时针、分针和秒针。

在 SimpleClock 应用程序运行后,它会每秒调用一次 AnalogClockFace.draw() 方法,如下所示:

    /** 
     * Called by the parent container when the display is being drawn. 
     */ 
    public override function draw():void 
    { 
        // stores the current date and time in an instance variable 
        currentTime = new Date(); 
        showTime(currentTime); 
    }

此方法将当前时间保存在变量中,因此在绘制时钟指针的过程中无法改变时间。然后,调用 showTime() 方法以显示指针,如下所示:

    /** 
     * Displays the given Date/Time in that good old analog clock style. 
     */ 
    public function showTime(time:Date):void  
    { 
        // gets the time values 
        var seconds:uint = time.getSeconds(); 
        var minutes:uint = time.getMinutes(); 
        var hours:uint = time.getHours(); 
 
        // multiplies by 6 to get degrees 
        this.secondHand.rotation = 180 + (seconds * 6); 
        this.minuteHand.rotation = 180 + (minutes * 6); 
 
        // Multiply by 30 to get basic degrees, then 
        // add up to 29.5 degrees (59 * 0.5) 
        // to account for the minutes. 
        this.hourHand.rotation = 180 + (hours * 30) + (minutes * 0.5); 
    }

首先,此方法提取当前时间的小时、分钟和秒的值。然后使用这些值来计算每个指针的角度。由于秒针会在 60 秒内旋转一圈,因此它每秒都会旋转 6 度 (360/60)。分针每分钟都旋转同样的度数。

时针每分钟都在更新,因此时针能够随着分针的跳动显示出某些时间变化过程。时针每小时旋转 30 度 (360/12),但也会每分钟旋转半度(30 度除以 60 分钟)。