Keeping time
December 4, 1997
by Pat McClellan
Dear Multimedia Handyman
I'm creating a game where I want to display how long it takes someone to complete a puzzle. When I base the time lapse on the tempo, it seems inconsistent from computer to computer. How should I track the time lapse?
Signed,
Keeps on Ticking
Dear Ticker,
Rather than basing your time on the tempo (which can vary on different machines), you're better off using "the timer" and "ticks" to count the time lapse. In Director, a "tick" is 1/60th of a second. A few other Lingo terms you need to know include "startTimer", which sets "the timer" = 0, and "mod" which is a mathmatical function which returns the remainder from a division operation. You can read the details of these Lingo terms in your Lingo Dictionary.
OK, so here's our strategy: we'll set the timer to 0, then as the ticks accumulate, we'll divide them by 60 to give us seconds, and divide by 3600 to give us minutes. We'll use the mod function so that after the seconds reach 60, they'll start over again. (You could use this same idea for minutes, but this example only goes up to an hour.) Finally, we'll need to put the minutes and seconds that we calculated into a standard time format (MM:SS) and plug that string into a field which is displayed on the stage. That's it.
I've written this as a behavior, so you can simply copy this & paste it into your behavior script. You'd attach the behavior to a field member called "timer" which is where the time will be displayed. Also, this behavior allows you to count UP or DOWN. If you count down, you can set the starting minutes and seconds.
-- Timer Behavio -- copyright ZZP Online, 1998. -- Free for use by readers of -- The Multimedia Handyman -- Visit property pstartMin property pstartSec property pCountUp -- time up (1) or count down (0) (default is down) property pMyField -- the name of the field to which the --behavior is applied property pStopTime -- a switch for the timer property pSecNow property pMinNow -- this handler allows the user -- to set the starting time -- and choose between counting up or down on getPropertyDescriptionList set p_list = [ ¬ #pCountUp: [ #comment: "Click for count UP:", ¬ #format: #boolean, ¬ #default: 0 ], ¬ #pStartMin: [ #comment: "Starting Minutes:", ¬ #format: #integer, ¬ #default: 0 ,¬ #range: [min:0,max:59]], ¬ #pStartSec: [ #comment: "Starting Seconds:", ¬ #format: #integer, ¬ #default: 0,¬ #range: [min:0,max:59]]¬ ] return p_list end -- The beginSprite handler adds -- the behavior object to -- "the actorList" so that we can -- use the stepFrame handler -- to update the time display on every new frame. on beginSprite me set pStopTime = FALSE add the actorList, me set pMyField = the name of member ¬ (the member of sprite the spriteNum of me) if NOT pCountUp then set pStartMin = pStartMin - 1 set pStartSec = pStartSec + 60 end if startTimer end -- The stepFrame handler checks -- to see whether to count -- up or down, then calls the -- appropriate handler. on stepFrame me if pCountUp then countUp me else if NOT pStopTime then countDown me end if end -- The countUp handler divides the ticks -- elapsed by 60 to yield -- seconds elapsed, and by 3600 to yeild -- minutes elapsed. By using -- the mod function with 60 as the parameter, -- the seconds will start -- over at 60. For example, when we get to -- 67 seconds, we only want -- to see ":07" in the seconds column. If -- we calculate 67 mod 60, the -- result is 7. on countUp me set secondsElapsed = the timer/60 set pSecNow = secondsElapsed mod 60 set pMinNow = the timer/3600 displayTime me end -- The countDown handler does the same as -- the countUp handler, except -- that it subtracts our elapsed time from -- the original start time. The -- last part of the handler checks to see -- if the timer is down to zero, -- and if so, it sets our property "pStopTime" -- to TRUE. When pStopTime -- is TRUE, the stepFrame handler stops -- calling this handler. on countDown me set secondsElapsed = the timer/60 set pSecNow = pStartSec - (secondsElapsed mod 60) set pMinNow = pStartMin - (the timer/3600) if pSecNow > 60 then set pMinNow = pMinNow + 1 set pSecNow = pSecNow - 60 end if displayTime me if pMinNow = 0 and pSecNow = 0 then set pStopTime = TRUE end if end -- Finally, the displayTime handler plugs -- the values for minutes and -- seconds elapsed into a variable called -- "showTime", then puts showTime -- into the field for display. on displayTime me if pSecNow = 60 then put pMinNow + 1 & ":00" into showTime else if pSecNow < 10 then put pMinNow & ":0" & pSecNow into showTime else put pMinNow & ":" & pSecNow into showTime end if put showTime into field "timer" end
You'll note that there are several places where I've had account for the fact that when you subtract time, you're dealing with base 60 values. For example, to subtract 20 seconds from 1 minute and 5 seconds, you have to change it to 0 minutes and 65 seconds.
Another thing to note in the displayTime handler is how I've dealt with putting together the string so that the seconds are always displayed as 2 digits.
Good luck with your project. I hope you'll experiment with this behavior, altering and improving it to meet your needs.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.