Counting down to the end of the world
March 22, 1999
by Pat McClellan
Dear Multimedia Handyman,
I'm trying to create a countdown clock for a screensaver that looks for the year 2000 and consequently calculates how long we have left ie: 277 days : 12 hours : 13 Mins etc. I would also like to then make a sprite move along a line in accordance with the present date.
Can you help me? I'm a novice with Director 7.
Colin Usher
Dear Colin,
Glad to see you're using Director 7. That means that we can use a Lingo function that is new to D7, the systemDate. This function returns the date (as set in the user's computer) in a predictable format that is capable of math functions. For example, the systemDate will return today's date, in the format (yyyy,mm,dd). That year in 4 digits, month in 2 digits, and day in 2 digits. That means that this format does not vary between US and European displays. So, we can set a variable to the last day of this century (1999,12,31), and then subtract the systemDate to get the number of days left.
Download the code in Mac or PC format
The next step is a little more complicated because D7 does not have time functions that are as useful as the systemDate. For time, use "the long time" to return a string which contains the hour, minute and second, as well as AM or PM. For example:
put the long time -- "10:51:36 AM"
We'll need to separate the hour, minute and second from this string. It's fairly easy to do. First, I'll set "the itemDelimiter" to be the colon. Then, I can refer to the hour as "item 1 of the long time". Minutes will be item 2. Seconds is trickier because item 3 is anything after that second colon, so the AM or PM gets included. So, before setting seconds = item 3, I have to delete these last 3 chars of the time (space, + AM or PM).
With the current hour, minute and second separated out, we can do our math calculations. Since we don't know if the user is on a 12 or 24 hour clock, we'll have to check for that with the AM/PM, and whether the hour is greater than 12. So, if the time contains AM or if the hour is greater than 12, we know we're safe subtracting the hour from 23 to get hours left. Otherwise, it must be afternoon or evening, and the displayed hour is less than 12 so we're on a 12 hour clock. That means we need to subtract the current hour from 11 to get hours left (in this day.)
Minutes and seconds are much easier. Subtract the current minutes from 59 to get minutes left in this hour, and subtract the current seconds from 59 to get the seconds left in this minute. NOTE: You use 59, because you would never want to display 60 minutes left. Instead, you'd display 1 hour and 00 minutes left. Same for seconds, and 23 or 11 for days.
The final step is simply to plug the values into a field or text cast member. Here's the behavior for the countdown.
-- Millennium Countdown Behavior -- copyright © 1999, ZZP Online, LLC -- Free use for readers of Director Online on exitFrame me set daysLeft = date(1999,12,31) - the systemdate set the itemDelimiter to ":" set timeNow = the long time set theHour = item 1 of timeNow set the floatPrecision = 0 --adjust for 24 hour clock if timeNow contains "AM" or theHour > 12 then set hoursLeft = string(23 - theHour) else set hoursLeft = string(11 - theHour) end if if hoursLeft contains "." then delete ¬ the last char of hoursLeft if the number of chars in hoursLeft < 2 ¬ then put "0" before hoursLeft -- crop off the AM/PM part set totalChars = the number of chars in timeNow delete char (totalChars - 2) to totalChars of timeNow set theMinute = item 2 of timeNow set minutesLeft = string(59 - theMinute) if minutesLeft contains "." then delete the ¬ last char of minutesLeft if the number of chars in minutesLeft < 2 ¬ then put "0" before minutesLeft set theSecond = item 3 of timeNow set secondsLeft = string(59 - theSecond) if secondsLeft contains "." then delete the last ¬ char of secondsLeft if the number of chars in secondsLeft < 2 then ¬ put "0" before secondsLeft -- put it into the display put daysLeft && "days" & RETURN into member "display" put hoursLeft && "hours" & RETURN after member "display" put minutesLeft && "minutes" & RETURN after member "display" put secondsLeft && "seconds" after member "display" end
Having the pointer move across a timeline is a little tricky. The key is that you have to figure out a "factor" which converts the number of increments where the pointer could be positioned (365 in our case) into the range of pixels (146 in the case of this demo).
You'll notice that I only bother to change the pointer's position on beginSprite. That means that it won't move if you happen to be running the program when the day changes. It would only move less than a half a pixel per day anyway, so I figured that it's ok to update the position only when the sprite first appears. If you want, you could have it update on every exitFrame, but that sure seems like a waste of processing.
property pRange, pTimeLineSpriteNum, pRight, pFactor, pSprite on getPropertyDescriptionList me set pdlist to [:] addprop pdlist, #pRange, [#comment:"Number of increments", ¬ #format:#integer, #default:365] addprop pdlist, #pTimeLineSpriteNum, [#comment:"Timeline ¬ SpriteNum", #format:#integer, #default:1] return pdlist end getPropertyDescriptionList on beginSprite me set timeWidth = the width of sprite pTimeLineSpriteNum set pFactor = timeWidth/float(pRange) set pRight = the right of sprite pTimeLineSpriteNum set pSprite = the spriteNum of me set daysLeft = date(1999,12,31) - the systemdate set the locH of sprite pSprite = pRight - (daysLeft * pFactor) put pRight put daysLeft put pFactor end
Hope that helps with your project!
Copyright 1997-2024, Director Online. Article content copyright by respective authors.