I’ve been itching to do one for a long time since I keep being asked to do countdown timers… Then there’s always that pesky deadline that keeps me from actually not cutting corners and doin’ it fo’ realz. So dundid I didit! A countdown timer set to server time via PHP!
(…You know, it should work, but I didn’t test it through n’ through, just threw the servertime integration together this evening :S ).
Source files up for grabs HERE!
The deal is if you do a countdown in Flash, the Flash Date object is set to the user’s system clock. If you decide to set your system time to… lets say… the year 2090 and beyond (or whatever) the countdown (of course) detects that the target date is so totally over.
Many clients think they’re sneaky and try to break your shit that way and then think that users will do the same.
Deal is no one cares, or really cares to try that, and if they do they know why the timer reads 00:00:00, BUT there are occasions where you’ll just want to do that (like in the case of ARG’s… or when the unexpected is expectable!)…
It’s Flash. There are always occasions where you’ll want to make an exception to the rule and do some weird experimental wizardry.
In AS you have two instances of the Date Object you need. One is the current date and one is the target date.
The current date is what you need to pass the server time too. From then on the rest is just classic countdown timer stuff… calculate target – current time left, break it down to seconds, minutes, hours, days, turn that to strings, blah, blah, etc…
I’m not the greatest PHP-ist in the world. In fact I get by. So this was (don’t laugh) a bit hard for me because it’s simple. Too simple!
Like any amateur, I tend to over complicate things when I don’t know what I’m doing… so, in trying to get the PHP date output to match that which Flash accepts, I was feeding it every combination of formats and date constants (D, d M Y H:i:s etc) under the sun.
Turns out you just need “r”.
Like so:
<?php $date = date("r", time()); echo $date; ?>
Update the .as file with the URL to your .php file.
Load that into Flash (via URLRequest), make sure it’s a string, and pass that string (in this case var loadedDateString:String) to the Date object via Date.parse.
Like so:
var currentDate:Date = new Date(Date.parse(loadedDateString));
That’s basically it.
Here’s a working example:
It’s a Counter.as class (view the AS HERE – right click + save as).
package { import flash.display.MovieClip; import flash.events.Event; import flash.events.TimerEvent; import flash.utils.Timer; import flash.events.TextEvent; import flash.net.URLLoader; import flash.net.URLRequest; public class Counter extends MovieClip { //Strings (Current count) private var sec:String; private var min:String; private var hrs:String; private var d:String; // (Previous count to check flip animation against) private var old_sec:String; private var old_min:String; private var old_hrs:String; private var old_d:String; //for holding the php servertime private var loadedDateString:String; // public function Counter(year:Number, month:Number, date:Number):void { //url loader & timer var ldr_servertime:URLLoader = new URLLoader(); var timer:Timer=new Timer(1000); timer.addEventListener(TimerEvent.TIMER, count); timer.start(); //Date object - !!!Months are counted from 0!!! var targetDate:Date=new Date(year,month,date); //count timer - magic happens here function count(e:TimerEvent):void { //load php ldr_servertime.load(new URLRequest("http://PATHTOFILE.COM/servertime.php")); ldr_servertime.addEventListener(Event.COMPLETE, onLoaded); //load the php servertime and pass it to loadedDateString for later parsing function onLoaded(evt:Event) { loadedDateString=ldr_servertime.data; } //current date feed it loadedDateString and parse it... like a boss var currentDate:Date=new Date(Date.parse(loadedDateString)); //calculate var timeLeft:Number=targetDate.getTime()-currentDate.getTime(); //remaining time to seconds, minutes, hours and days var seconds:Number=Math.floor(timeLeft/1000); var minutes:Number=Math.floor(seconds/60); var hours:Number=Math.floor(minutes/60); var days:Number=Math.floor(hours/24); seconds%=60; minutes%=60; hours%=24; //numbers to strings sec=seconds.toString(); min=minutes.toString(); hrs=hours.toString(); d=days.toString(); //if single digit "0" infront if (sec.length<2) { sec="0"+sec; } if (min.length<2) { min="0"+min; } if (hrs.length<2) { hrs="0"+hrs; } //SET OLD/NEW VALUES FOR FLIP ANIMATIONS old_d=txt_day.text; old_hrs=txt_hour.text; old_min=txt_min.text; old_sec=txt_sec.text; //SET TEXT; txt_day.text=d; txt_hour.text=hrs; txt_min.text=min; txt_sec.text=sec; //flip animation if (old_sec!=sec) { mc_ov_sec.gotoAndPlay(1); } if (old_min!=min) { mc_ov_min.gotoAndPlay(1); } if (old_hrs!=hrs) { mc_ov_hrs.gotoAndPlay(1); } if (old_min!=min) { mc_ov_hrs.gotoAndPlay(1); } if (old_d!=d) { mc_ov_d.gotoAndPlay(1); } //IS OVER? //check if current date has passed target date so it doen'st keep counting past the due date if (currentDate>=targetDate) { timer.removeEventListener(TimerEvent.TIMER_COMPLETE, count); //just 00 the text fields so it looks "over" txt_day.text="00"; txt_hour.text="00"; txt_min.text="00"; txt_sec.text="00"; } } } } }
To use, simply create an instance of it, feed it the date you want it to count down to (format is YEAR, MONTH, DAY) and attach it to the stage via addChild.
var _counter:Counter = new Counter(2011,4,11); addChild(_counter);
Just make sure you have the movieclip (in the library) linked to the class.
Select the clip > Properties and in ‘Class’ point it to ‘Counter’.
That’s it!
Source files up for grabs HERE!
Hi!
Thanks for Your great tutorial!
Just one question: in Your Class there is:
mc_ov_sec
mc_ov_min
mc_ov_hrs
mc_ov_hrs
mc_ov_d
Where and how to instantiates them?
Sorry for my bad english!
Again, thank You!
Hey, those are instance names of movieclips. Remove them, or substitute them for something different.