My company is producing a New Year's Event and I am trying to figure out a way to generate a six hour countdown into the new
millennium. Does Director have any special capability of generating accurate countdowns
Well, yes and no. Director can handle time functions to accurately interface with a computer's system clock, but the countdown part requires a little lingo. It isn't too terribly difficult to create a simple countdown timer to a specific date, but just for fun, lets make one we can reuse for anything. To track the timer we will need a few things...
An "end date"
A set of field/text members to display the results
A field to show that we are either approaching the date and time or that we have already passed it
Lets start with the date. Thanks to Director 7 we now have full access to the system's date functions. Before Director 7 we had to rely on either the standard date functions, which could vary from country to country, or the use of a 3rd party Date/Time Xtra. Now we have the systemDate property that can return the system's clock date in a set format...
put the systemDate
-- date( 1999, 12, 27 )
We can also create date objects the same way and do addition and subtraction routines on them...
put date(2000, 1, 1) - the systemDate
-- 10
Using these properties we can easily get the number of days until a specific event. Time is a little trickier. Director can return time in a number of formats. We are interested in "the long time" as it returns hour, minute, seconds, and AM and PM info.
put the long time
-- "1:20:57 PM"
Since this is a string we need to break each piece down with the item delimiter property and for the seconds use the first 2 characters of item 3 and the AM/PM info is the last 2 characters of item 3.
Now that we have that we start our subtraction routines to figure out how much longer we have to wait for the long awaited event. We can start by basic subtraction. We start by doing the basics. Waiting hour - current hour, waiting minute - current minute, etc. Once we do this we need to then look at which ones are negative. For example, if we are waiting for a time ending in 30 seconds, then what happens when the current time ends in 59 seconds. To accomplish this we use the old 3rd grade math routine of "borrowing". By taking 1 minute from the minutes group and converting to 60 seconds we end up with a positive number. We subtract that minute and repeat with minutes, hours and finally days. Now all values should be accurate. Using this collected information we can toss out a sendAllSprites command to all the fields to update their values.
If we have passed the day we just do the same thing with the current date/time - the "waiting" date/time. That's all there is to it. Below is the code...
--Copyright 1999 Chuck Neal
--chuck@mediamacros.com
--If you find this code helpful, send me an e-mail and let me know. :-)
on getPropertyDescriptionList me
p_list = [:]
if [#field, #text].getOne(sprite(the currentSpriteNum).member.type) = 0 then
--not a text or field member, use as the counter "base"
p_list.addProp(#cYear, [#format : #integer, #comment : "Countdown year (in 4 digit format):", #default : 2000])
p_list.addProp(#cMonth, [#format : #symbol, #comment : "Countdown month:", #default : #January, #range : [#January, #February, #March, #April, #May, #June, #July, #August, #September, #October, #November, #December]])
p_list.addProp(#cDay, [#format : #integer, #comment : "Countdown Day:", #default : 1, #range : [#min : 1, #max : 31]])
p_list.addProp(#cHour, [#format : #integer, #comment : "Countdown Hour:", #default : 0, #range : [#min : 0, #max : 23]])
p_list.addProp(#cMin, [#format : #integer, #comment : "Countdown minute:", #default : 0, #range : [#min : 0, #max : 59]])
p_list.addProp(#cSec, [#format : #integer, #comment : "Countdown second:", #default : 0, #range : [#min : 0, #max : 59]])
p_list.addProp(#whatItem, [#format : #symbol, #comment : "What item is this?:", #default : #Master, #range : [#Master]])
else
--is a field, which one?
p_list.addProp(#whatItem, [#format : #symbol, #comment : "What item is this?:", #default : #Day, #range : [#Day, #Hour, #Min, #Second, #All, #UntilSince]])
end if
return p_list
end
on exitFrame me
if whatItem = #master then
--only run on the master control
theMonth = [#January, #February, #March, #April, #May, #June, #July, #August, #September, #October, #November, #December].getOne(cMonth)
theDays = date(cYear, theMonth, cDay) - the systemDate
theTime = getTime()
if theDays > 0 then
--before the day
beforeAfter = "before"
else if theDays < 0 then
--after the day
beforeAfter = "after"
else
--same day, dig deeper
if theTime[1] > cHour then
beforeAfter = "after"
else if theTime[1] < cHour then
beforeAfter = "before"
else
--same hour, dig deeper
if theTime[2] > cMin then
beforeAfter = "after"
else if theTime[2] < cMin then
beforeAfter = "before"
else
--same min, dig deeper
if theTime[3] > cSec then
beforeAfter = "after"
else
beforeAfter = "before"
end if
end if
end if
end if
timeList = getDate(me, theDays, theTime, beforeAfter)
sendAllSprites(#updateCount, timeList, beforeAfter)
end if
end
on updateCount me, timeList, beforeAfter
case whatItem of
#Day :
sprite(spriteNum).member.text = string(timeList[1])
#Hour :
sprite(spriteNum).member.text = string(timeList[2])
#Min :
sprite(spriteNum).member.text = string(timeList[3])
#Second :
sprite(spriteNum).member.text = string(timeList[4])
#All :
sprite(spriteNum).member.text = timeList[1] && "," && timeList[2] & ":" & timeList[3] & ":" & timeList[4]
#UntilSince :
if beforeAfter = "after" then
sprite(spriteNum).member.text = "Since"
else
sprite(spriteNum).member.text = "Until"
end if
end case
end
on getTime me
baseTime = the long time
the itemDelimiter = ":"
thisHour = integer(baseTime.item[1])
thisMin = integer(baseTime.item[2])
thisSec = integer(baseTime.item[3].char[1..2])
numChars = baseTime.char.count
amPm = baseTime.char[(numchars - 1)..numChars]
if amPm = "pm" then
if thisHour < 12 then
thisHour = thisHour + 12
end if
else
if thisHour = 12 then
thisHour = 0
end if
end if
return [thisHour, thisMin, thisSec]
end
on getDate me, theDays, theTime, beforeAfter
if beforeAfter = "before" then
theSec = cSec - theTime[3]
theMin = cMin - theTime[2]
theHour = cHour - theTime[1]
else
theSec =theTime[3] - cSec
theMin = theTime[2] - cMin
theHour = theTime[1] - cHour
end if
if theSec < 0 then
--wrap around and borrow from the minutes
theSec = theSec + 60
tOffset = 1
else
tOffset = 0
end if
theMin = theMin - tOffset
if theMin < 0 then
--wrap around and borrow from hours
theMin = theMin + 60
tOffset = 1
else
tOffset = 0
end if
theHour = theHour - tOffset
if theHour < 0 then
--wrap around and borrow from the days
thehour = 24 + theHour
tOffset = 1
else
tOffset = 0
end if
theDays = theDays - tOffset
return [theDays, theHour, theMin, theSec]
end
on getBehaviorDescription me
describe = "This is a basic countdown behavior. Drop it on a non text/field member to set up the master timer and then drop it on each field/text member you want to use to display."
describe = describe & return & "Once it passes the date it can turn a field from saying " & quote & "Until" & quote & " to one saying " & quote & "Since" & quote
return describe
end
You can add your own custom output, or even have it trigger an animation, etc when the countdown reaches 0. Just play with it and have fun.
Contact
MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA