Determining the Passage of Time


The getTimer() function returns (in milliseconds) the length of time elapsed since the movie was first opened and played; therefore, if the movie has been open for six seconds, the following script:

 var playBackTime:Number = getTimer(); 

would assign playBackTime a value of 6000 (1,000 milliseconds for each second). This is an accurate and precise representation of time based on the user's system clock and is not dependent on the movie's frame rate, the user's processor speed, or whether the movie is playing. This is also a universal value, which means that it represents the playback of the movie as a whole; you cannot track the length of time for which individual timelines have been present.

By setting a variable's value based on the value returned by the getTimer() function and comparing that value to the value returned by the function at a later point in time, you can evaluate the amount of time (too much or too little) that has passed within that span, and take appropriate action. To better understand this principle, consider the following example:

 // Button A functionality var startTime:Number; buttonA_btn.onRelease = function() {   startTime = getTimer(); } // Button B functionality var nowTime:Number; buttonB_btn.onRelease = function() {   nowTime = getTimer();   if (nowTime - startTime < 1000) {     message_txt.text = "You press buttons pretty quickly";   } else {     message_txt.text = "You're pretty slow";   } } 

Here, the action on one button (buttonA_btn) establishes a starting point by capturing the time when the button is pressed and released. When buttonB_btn is pressed and released, the time is captured again. A conditional statement is then used to determine whether the amount of time between these two button presses was more or less than a second and then acts accordingly. Similarly, by using the following script, you can facilitate double-clicking functionality for a button that is, the script takes action only if separate clicks occur within a half-second of each other.

 var lastClick:Number; myButton_btn.onRelease = function(){   if(getTimer() - lastClick < 500) {     // Actions   } lastClick = getTimer(); } 

By integrating the getTimer() function with the onEnterFrame event and some conditional statements, you can create a mechanism that triggers actions at specific times, independently of the timeline and with much greater accuracy. Look at the following example:

 slideShow.onEnterFrame = function() {   if (getTimer() > 5000) {     // Actions   }   if (getTimer() > 10000) {     // Actions   }   if (getTimer() > 15000) {     // Actions   } } 

This script triggers actions every five seconds while the movie plays. This is often the most accurate way of executing actions at specific points in time during a movie's playback.

In the following exercise, we'll use the getTimer() function to create a timer/alarm.

  1. Open makeMyDay2.fla.

    We'll continue building on the project from the preceding exercise. This time around, however, we'll work on the Alarm section of the application. This section of the project contains three NumericStepper component instances named minutes, seconds, and loops, which control when the alarm goes off as well as how many times the alarm sound plays.

    Next to these NumericStepper instances is a Button component instance named start_btn that starts the timer/alarm.

    Above these elements is a movie clip instance named clock_mc, which includes several moving elements (just like a real timer). Let's take a look at those.

    graphics/16inf11.gif

  2. Double-click the clock_mc movie clip instance to edit it in place.

    This timeline contains two layers: the Graphic layer contains the main clock graphic, and the Hands layer contains three movie clip instances that represent various indicators on the clock face. The secondHand_mc movie clip represents the clock's second hand, which rotates and simulates a tick each second the timer is on. Just below this instance is a movie clip instance named minuteHand_mc, which also rotates but at 1/10 the speed of the second hand (just as on a real clock). The third movie clip instance appears as a small red tick mark at the top of the clock. Named alarmHand_mc, this instance rotates when the timer is started, to indicate when the alarm is set to go off.

    graphics/16inf12.gif

    The functionality of the Alarm section of the application will be handled by two main functions: one for starting the alarm timer, and another for stopping the timer and playing the alarm sound. All the script for this exercise will be placed on Frame 1 of the application.

  3. Return to the main timeline. With the Actions panel open, select Frame 1 of the Actions layer and add the following script at the end of the current script:

     start_btn.onRelease = function (){   alarmOn(); } 

    This step attaches an onRelease event handler to the start_btn instance. When this event is triggered, the alarmOn() function (which we have yet to script) is called. This function turns on the timer and activates the alarm.

  4. Add the following script at the end of the current script:

     var startingTime:Number; function alarmOn(){ } 

    The first line creates a variable named startingTime, which eventually will hold a numeric value representing the split second when the timer is started. The remaining two lines are the beginning of the alarmOn() function. As described in Step 3, this function is called when the start_btn instance is clicked.

  5. Insert the following line of script within the alarmOn() function:

     startingTime = getTimer(); 

    When this function is executed, the startingTime variable's value is set to a numerical value representing the length of time (in milliseconds) that has elapsed since the movie was first opened and played. Capturing the exact time at which the timer was started is critical to making the Alarm section of the project work properly we'll explain why in a moment.

  6. Insert the following event handler after the line of script added in Step 5:

     clock_mc.onEnterFrame = function() { } 

    graphics/16inf13.gif

    As a result of the alarmOn() function being called, this onEnterFrame event handler gets attached to the clock_mc instance. In the next few steps, we'll add several lines of script within this event handler, which will execute every time the onEnterFrame event occurs (24 times a second).

  7. Add the following line of script within the onEnterFrame event handler:

     var totalTimeToAlarm = (minutes.value * 60) + seconds.value; 

    Remember that our scene contains one NumericStepper component instance for entering minutes (named minutes) and another for entering seconds (named seconds). Used together, they determine how much time should elapse before the alarm goes off. The line of script in this step converts the minutes entered to seconds and then adds that figure to the seconds entered, to come up with the total time (in seconds) that must elapse before the alarm sounds.

    Before we explain how the expression is evaluated, note that it makes reference to a value property in relation to both the minutes and seconds NumericStepper instances. This property simply represents the current numeric value displayed in the instance.

    Using parentheses in the expression, we've sectioned it off into two parts: (minutes.value * 60) is added to seconds.value to determine the value of totalTimeToAlarm. To understand how this expression works, let's look at an example. Assume that the user has entered a value of 5 into the minutes instance and 37 into the seconds instance. Using these values, the expression would initially look like this:

     (5 * 60) + 37 

    Because there are 60 seconds in a minute, you can get the seconds equivalent of the minutes entered by multiplying the value entered for minutes by 60. In this case, the result is 300. This value is then added to the actual seconds entered to give a final total of 337 (seconds), which is assigned to totalTimeToAlarm. Eventually our script will compare this value with the number of seconds that have passed since the timer was started. After the passing seconds exceed the value of totalTimeToAlarm, the script knows that it's time to sound the alarm more on this topic in a bit.

    NOTE

    Although the timer would work just fine if the value of totalTimeToAlarm was set just once, by placing this line of script within the onEnterFrame event handler we enable the variable's value to be updated 24 times a second (the frame rate of the movie) if necessary. This allows the user to reset the minute and second settings of the timer dynamically that is, while the timer is on and update the value of totalTimeToAlarm automatically, affecting when the alarm sounds.

  8. Add the following line of script after the line you added in Step 7:

     var secondsElapsed = Math.round((getTimer() - startingTime) / 1000); 

    It's critical that our script track the amount of time that has elapsed since the user clicked the Start button and activated the timer. That's what this line of script does. Understanding the precedence in this expression, we know that it's evaluated in the following manner:

    Using the getTimer() function, the current time (which is checked 24 times a second) is subtracted from the value of startingTime:

     getTimer() - startingTime 

    Remember that the value of startingTime is set to the current time at the point when the Start button is clicked and the alarmOn() function is called. By constantly checking and subtracting the current time from that value, the script can determine how many milliseconds have elapsed between the current time and the time the Start button was pressed. As we mentioned earlier, this part of the expression results in a millisecond value, such as 29349. If you divide this value by 1,000, as the next part of the expression does (/ 1000), you get a result of 29.349 equal to 29.349 actual seconds. The last part of the expression rounds the value:

     Math.round() 

    In the end, secondsElapsed would be assigned a value of 29. Remember, however, that this value continues to increment as long as the script executes because the difference between the current time and the time the Start button was pressed continues to increase. Also, because the Math.round() method is used in the expression, its value increments only in whole numbers 29, 30, 31, and so on. This provides us with the amount of time that has elapsed accurate to 1/24 of a second because that's how often the line of script is executed.

    graphics/16inf14.gif

    At this point, we have two variable values that will facilitate the rest of the actions in this script.

  9. Add the following line of script just below the one added in Step 8:

     clock_mc.alarmHand_mc._rotation = totalTimeToAlarm / 10; 

    Remember that alarmHand_mc is the instance name of the hand (red tick mark) inside the clock_mc movie clip instance that indicates (on the clock's face) when the alarm is set to go off. This line of script sets the alarmHand_mc rotation so that it can perform this functionality. For example, if the alarm is set to go off in 20 minutes, the alarmHand_mc instance needs to be rotated so that the red tick mark in the instance appears at the 20-minute mark on the clock's face. Let's look at how this expression accomplishes that goal.

    A full circular rotation is 360 degrees. By breaking this rotation into the 60 points on a clock's face that represent minutes, we can determine that each minute needs to represent a rotation of 6 degrees (6 x 60 = 360); therefore, to move the alarmHand_mc movie clip instance to the 20-minute point, it must be rotated 120 degrees (6 degrees per minute x 20 minutes). Using the expression that sets the value of totalTimeToAlarm (as shown in Step 7), 20 minutes would be converted to 1,200 seconds. The script in Step 9 then divides this value by 10, resulting in rotating alarmHand_mc by 120 degrees where it must be to indicate that the alarm will go off in 20 minutes.

    graphics/16inf15.jpg

    NOTE

    Because the minute and second values that the user sets can be changed while the timer is on, and this script uses that total time to rotate this instance, changing those values changes the rotation to reflect the updated values.

  10. Add the following lines of script after the line added in Step 9:

     clock_mc.secondHand_mc._rotation = secondsElapsed * 6; clock_mc.minuteHand_mc._rotation = secondsElapsed / 10; 

    These two lines rotate the secondHand_mc and minuteHand_mc movie clip instances (inside clock_mc), based on the continually updated value of secondsElapsed. The logic that makes this occur is again based on the fact that a full circular rotation is 360 degrees, and the clock face is split into 60 graduations (both minutes and seconds) of 6 degrees each. For each second that elapses, the second hand needs to move 6 degrees, representing one second. Knowing this, the first action in Step 10 sets the rotation of the secondHand_mc movie clip instance to the value of secondsElapsed multiplied by 6. At one second it's rotated 6 degrees, at two seconds 12 degrees, and so on, making it appear to tick like a real clock.

    The minute hand functionality requires a slightly different approach. The minute hand on a clock usually rotates at 1/60 the pace of the second hand. For example, if 60 seconds have ticked away, the second hand has made a full rotation. At this point, the minute hand should have rotated just 6 degrees on the clock face, indicating that one minute has passed. Knowing this, the second action in Step 10 sets the rotation of the minuteHand_mc movie clip instance based on the value of secondsElapsed divided by 10. Thus, if 60 seconds pass, this expression evaluates to a value of 6, which is the amount that minuteHand_mc has rotated.

    In the end, the secondHand_mc movie clip instance is rotated six times the value of secondsElapsed, while the minuteHand_mc instance is rotated 1/10 that same value. The minuteHand_mc instance rotates 1/60 as much as the secondHand_mc instance, just like on a real clock.

    Because the value of secondsElapsed is constantly being updated, both of these hands are in constant motion while the timer (the entire script we've been working on) is turned on.

  11. Add the following conditional statement after the actions added in Step 10:

     if (secondsElapsed >= totalTimeToAlarm) {   activateAlarm(); } 

    This conditional statement, which is executed 24 times a second like all the other actions in the onEnterFrame event handler, compares the value of secondsElapsed to the value of totalTimeToAlarm. When both have the same value (indicating that it's time for the alarm to sound), this statement becomes true and the action within the statement is executed, calling the activateAlarm() function, which in turn causes the actions of the activateAlarm() function to be executed. This function is defined next.

    The alarmOn() function definition is now complete!

    graphics/16inf16.gif

  12. Add the following script just below the current script:

     var alarmSound:Sound = new Sound(); function activateAlarm() {   delete clock_mc.onEnterFrame;   clock_mc.secondHand_mc._rotation = 0;   clock_mc.minuteHand_mc._rotation = 0;   clock_mc.alarmHand_mc._rotation = 0;   alarmSound.attachSound("alarm");   alarmSound.start(0, loops.value); } 

    The first line creates a Sound object named alarmSound, which eventually will contain the alarm sound to be played. The remaining lines define the activateAlarm() function.

    The first thing the function does is delete the onEnterFrame event handler attached to the clock_mc instance when the alarmOn() function was called. This action causes the timer to stop functioning. The next three actions in the function reset the rotation of the various hands on the clock to their starting positions. The next action attaches the sound named alarm in the library to the alarmSound Sound object. The last action uses the start() method to play that sound. The first parameter of the method determines how many seconds into the sound it should begin to play; the second parameter determines how many times the sound should loop. Because we want the sound to start playing at its beginning, we set the first parameter to 0. The value of the second parameter is set based on what the user inputs into the loops NumericStepper instance.

  13. Choose Control > Test Movie to view the project to this point.

    When the movie appears, use the NumericStepper instances to input time values for the timer; then click the Start button. The various hands on the clock should go into action. When the alarm time is reached, the timer turns off, its hands are reset, and the alarm sounds and continues to loop based on the value entered into the loops instance.

  14. Close the test movie and save the project as makeMyDay3.fla.

    As you've seen in this lesson, the getTimer() function plays a vital role in interactivity that requires an accurate measurement of time to function properly.

    We'll continue building on this file in the next exercise.



Macromedia Flash MX 2004 ActionScript(c) Training from the Source
Macromedia Flash MX 2004 ActionScript: Training from the Source
ISBN: 0321213432
EAN: 2147483647
Year: 2005
Pages: 182

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net