Flashで時計作る時に - 「TeraClock」ライブラリ作りました

Posted by admin on 9 月 02, 2008
NEWS

簡単に Flash で時計が作れる AS3 用ライブラリ「TeraClock」を公開しましたー。 最近 THA さんの展示や APMT の発表を見て、時計が作りたくなった人もいるかと思いますのでどうぞお使いください。慣れれば新規ファイル作成から3分ぐらいで Flash 時計が作れます。あとは表現です。 …

簡単に Flash で時計が作れる AS3 用ライブラリ「TeraClock」を公開しましたー。
最近 THA さんの展示APMT の発表を見て、時計が作りたくなった人もいるかと思いますのでどうぞお使いください。慣れれば新規ファイル作成から3分ぐらいで Flash 時計が作れます。あとは表現です。

とりあえず簡単な使い方をスクリーンキャストにしました。(音出ます!)

前回の TeraFire 同様、今回も Spark Project 内にライブラリを置いてありますので、SVN 取得してください。やり方は TeraFire のビデオとか WebDesigning の8月号に載ってます。フルパスは以下:

http://www.libspark.org/svn/as3/TeraClock/src/com/trick7/utils/TeraClock.as

主な機能

ちょっとややこしい文章なので、上のビデオ見たあとに読んでいただいたほうがいいかもです。

  • 時(HOURS_CHANGED)・分(MINUTES_CHANGED)・秒(SECONDS_CHANGED)それぞれの更新タイミングをイベントとして受け取れます。秒イベントで関数動かしつつ、別途時報イベントで別関数を実行とかが簡単にできます。
    とはいえ、よく見かける「ピッ(57)・ピッ(58)・ピッ(59)・ポーン(00)」的な「○秒の時に○○する」ってのがしたい場合は TeraClock.SECONDS_CHANGED リスナーの関数内で if 分岐させてください。
  • 時・分・秒の各値は、(TeraClockインスタンス名).seconds とかで取得できます。秒の値に応じてオブジェクトのサイズ変形とかするときはこっちですね。

    一方、デジタル数字で表示させたい時は、たとえば5秒のときは「05」にしたいですよね。そういうときは2桁モードとして、(TeraClockインスタンス名).seconds2ってやると常に2桁になるようにしてあります。
  • コンストラクタのパラメータにタイムゾーンを渡してやると世界各国の時間が表示されます。日本は世界標準時間から +9:00で、new TeraClock(9); としてやれば日本時計になりますが、9って指定しなくてもデフォルトで日本時計になるようにしてあります。ハワイは -10:00 なので new TeraClock(-10); とするわけですね。各国のタイムゾーンは Windows の時計をダブルクリックして確認しましょう。ただサマータイムは未実装なのでご注意。

実際に作ってるとこ見た方がわかりやすいので、ちまちま使用例ビデオを作っていこうとは思っています。

これから調べること

とりあえず公開してみんなに突っ込んでもらえて「完全な時計生成ライブラリ」になればいいなとか思ったりしていますが、コンストラクタとメソッドは崩さないようにしたい心持ちでいます。

  • EventDispatcher クラスを継承させたカスタムイベント用の別ファイル(例えばClockEvent.as)を作ろうか迷ったけど、コンストラクタで if 分岐で super(SECONDS_CHANGED);とかができなくてとりあえずやめた。
  • 結果1個の as ファイル(TeraClock.as)に記述する形になったのだけど、ENTER_FRAME させてるし、EventDispatcher も継承してるし Sprite 型にしたのだけど、なんか Sprite でいいのかなぁと不安。もっと絞れないかなぁ。
  • ENTER_FRAME イベントで毎フレーム時間を取得している仕様なので、すっごい実行してる感があるから、ここは Timer クラスを使った方が・・とか思っていたのだけど、実はそもそも Timer クラスの中で ENTER_FRAME が動いてるらしく、それだったら ENTER_FRAME させたほうがいいと twitter で教えてもらった。
  • で、カスタムイベントもその中で定義しているのだけど、呼び出し側のイベントハンドラ関数の引数んとこが (e:Event) じゃないと動かないらしい。
  • サマータイム実装するかなぁ。コンストラクタの第2パラメータの Boolean でやるかもだけど、それやると各国間の時差取得系のメソッドは実装しにくくなりそう。
  • 毎フレーム余計な処理を控えたかったので日時取得系は TeraCalender クラスとかで別途作る予定。

ソースコードとか

リファレンス代りに貼っておきます。まずはライブラリ本体(TeraClock.as)

package com.trick7.utils {
	import flash.display.*;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	/**
	* @author tera
	*/
	public class TeraClock extends Sprite {
		public static const HOURS_CHANGED = "hoursChanged";
		public static const MINUTES_CHANGED = "minutesChanged";
		public static const SECONDS_CHANGED = "secondsChanged";
		private var _hours:int;
		private var _minutes:int;
		private var _seconds:int;
		private var _preSeconds:int;
		private var _gmt:int;
		// コンストラクタ関数。引数でタイムゾーンを設定できる。デフォルトは+9:00(日本)
		public function TeraClock(GMT:int = 9) {
			_gmt = GMT%24;
			addEventListener(Event.ENTER_FRAME, enterFrameListener);
		}

		private function enterFrameListener(e:Event):void {
			var date = new Date();
			if(_gmt>=0){
				_hours = (date.getUTCHours() + _gmt) % 24;
			}else {
				_hours = (24+(date.getUTCHours() + _gmt)) % 24;
			}
			_minutes = date.getUTCMinutes();
			_seconds = date.getUTCSeconds();
			if (_seconds != _preSeconds) {
				//trace(_hours + ":" + _minutes + ":" + _seconds);
				dispatchEvent(new Event(SECONDS_CHANGED));
				if (_seconds == 0) {
					dispatchEvent(new Event(MINUTES_CHANGED));
					if (_minutes == 0) {
						dispatchEvent(new Event(HOURS_CHANGED));
					}
				}
			}
			_preSeconds = _seconds;
		}
		// 外部から値を取得するためのゲッター。セッターはとりあえずいらないや。
		public function get hours():int { return _hours; }
		public function get minutes():int { return _minutes; }
		public function get seconds():int { return _seconds; }
		// 1桁の数の時を2桁にする。返り値は String 型になる。
		public function get hours2():String { return niketa(_hours); }
		public function get minutes2():String { return niketa(_minutes); }
		public function get seconds2():String { return niketa(_seconds); }
		// 2桁にして返す関数
		private function niketa(num:int):String {
			if (num < 10) {
				return String("0"+num);
			}else {
				return String(num);
			}
		}
	}
}

以下がその使用例。ドキュメントクラス Main.as とした場合:

package  {
	import flash.events.Event;
	import flash.display.Sprite;
	import com.trick7.utils.TeraClock;
	public class Main extends Sprite{
		public var clock:TeraClock;
		public function Main() {
			clock = new TeraClock();
			clock.addEventListener(TeraClock.SECONDS_CHANGED, secondsListener);
			clock.addEventListener(TeraClock.MINUTES_CHANGED, minutesListener);
			clock.addEventListener(TeraClock.HOURS_CHANGED, hoursListener);
		}

		private function secondsListener(e:Event):void {
			trace(clock.seconds + "秒です。現在:" +clock.hours2+":"+clock.minutes2+":"+clock.seconds2+" です。" );
		}
		private function minutesListener(e:Event):void {
			trace(clock.minutes +"分になったよ。");
		}
		private function hoursListener(e:Event):void {
			trace(clock.hours+"時になったよ。");
		}
	}
}

コメントはまだありません。

コメントをどうぞ

WP_Big_City