Articles Archive
Articles Search
Director Wiki

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?


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
-- 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
-- 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
-- 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
-- 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
-- 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
    put pMinNow & ":" & pSecNow into showTime
  end if
  put showTime into field "timer"

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.

Patrick McClellan is Director Online's co-founder. Pat is Vice President, Managing Director for Jack Morton Worldwide, a global experiential marketing company. He is responsible for the San Francisco office, which helps major technology clients to develop marketing communications programs to reach enterprise and consumer audiences.

Copyright 1997-2019, Director Online. Article content copyright by respective authors.