Hello. I have a new blog.

I've moved this blog to the following URL Kerkness.ca. Thank you for visiting, please update your bookmarks.

Saturday, March 1, 2008

Display a time counter in flex

For my Sudoku game I wanted to add a simple counter which shows how much time has passed since a user started their game. Should be simple enough, just create a Timer object and have it update a display every second. The problem I ran into was how to easily display the number of seconds passed as a readable time format (example HH:MM:SS). I searched high and low for any type of formatting function which would help but came up short and had to figure out something on my own.

What I came up with feels like a total hack and I'm certain there has to be a better way to solve this problem. Anyway, here is my code, it appears to work just fine but would appreciate it if anyone knows of a better solution.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" creationComplete="init()">
<mx:Script>
<![CDATA[
// Create Timer object to fire every second with no end
private var myTimer:Timer = new Timer(1000);

private function init():void
{
// Add event listener for the time
myTimer.addEventListener(TimerEvent.TIMER,clockTick);
myTimer.start();
}
// function to update display
private function clockTick(event:TimerEvent):void
{
var fullseconds:Number = Timer( event.currentTarget ).currentCount;
var fullminutes:Number = Math.floor(fullseconds/60);
var hours:Number = Math.floor(fullseconds/3600);
var minutes:Number = ( hours > 1 ) ? Math.round((fullseconds-(hours*3600))/60) : Math.floor(fullseconds/60) ;
var seconds:Number = ( fullseconds > 60 ) ? fullseconds-(fullminutes*60) : fullseconds;
var hourstr:String = ( hours < 10 ) ? '0'+hours.toString() : hours.toString();
var minstr:String = ( minutes < 10 ) ? '0'+minutes.toString() : minutes.toString();
var secstr:String = ( seconds < 10 ) ? '0'+seconds.toString() : seconds.toString();
if ( minstr == '60' ) minstr = '00';
if ( secstr == '60' ) secstr = '00';
myClock.text = hourstr+':'+minstr+':'+secstr;
}
]]>
</mx:Script>
<mx:Label id="myClock" />
</mx:Application>

The one part which really bugs me about this is manually adding a '0' to numbers less than 10. If I was working in PHP this would be no problem but being a n00b with actionscript this is the best I could come up with in the hour I had to work on it.

2 comments:

  1. I had to do this recently as well. I wound up creating a custom Formatter, like this:

    package util.formatters
    {
    import mx.formatters.Formatter;

    public class TimeCodeFormatter extends Formatter
    {
    // Value is should be a Number, representing milliseconds
    override public function format(value:Object):String
    {
    var ms:Number = Number(value);

    var s:Number = Math.floor(ms / 1000);
    var m:Number = Math.floor(s / 60);
    var h:Number = Math.floor(m / 60);

    s %= 60;
    m %= 60;
    h %= 24;

    return pad(h) +':'+ pad(m) +':'+ pad(s);
    }

    private function pad(num:Number):String
    {
    return ( num < 10 ) ? "0"+num : num.toString();
    }
    }
    }

    ReplyDelete
  2. Thanks for the comment. That is a nice and cleaner approach than my own solution.

    ReplyDelete

Thank you for the comments.