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

簡単に Flash で時計が作れる AS3 用ライブラリ「TeraClock」を公開しましたー。SparkProject 上で公開しています。
最近 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 の時計をダブルクリックして確認しましょう。ただサマータイムは未実装なのでご注意。
  • uranodai さんが AS2 用に TeraClock を移植してくださいました!Spark においてあります(http://www.libspark.org/svn/as2/TeraClock/)。ありがとうございますー。
  • さくーしゃさんが、「時・分・秒」の各「00」の10の位・1の位を別々の値(int型)として取得できる機能を追加してくださいました。(AS3版のみ)
  • タロタローグ ブログの人が、コンストラクト直後に時間取得できるように改修してくださいました。これで、new TeraClock(); 直後に時間取得可能になりました。(それまではSECONDS_CHANGEDイベントで取得する感じだったのです。これもAS3版のみ)

これから調べること

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

  • 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
* サンプルコード(ドキュメントクラスとして設定すれば動きます):
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.hours+":"+clock.minutes+":"+clock.seconds+" です。" );
}
private function minutesListener(e:Event):void {
trace(clock.minutes +"分になったよ。");
}
private function hoursListener(e:Event):void {
trace(clock.hours+"時になったよ。");
}
}
}
*/
public class TeraClock extends Sprite {
public static const HOURS_CHANGED:String = "hoursChanged";
public static const MINUTES_CHANGED:String = "minutesChanged";
public static const SECONDS_CHANGED:String = "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: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桁返す
public function get hoursUpper():int { return _hours / 10; }
public function get minutesUpper():int { return _minutes / 10; }
public function get secondsUpper():int { return _seconds / 10; }
// 下位1桁返す
public function get hoursLower():int { return _hours % 10; }
public function get minutesLower():int  { return _minutes % 10; }
public function get secondsLower():int { return _seconds % 10; }
// 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);
}
}
//アナログ時計にした時の針の角度を返す。針のムービークリップは右方向を向けてに作成・配置しておくこと。(9/17追加)
public function get hoursDegree():Number {
return ((_hours % 12) * 30 - 90) + (_minutes / 2) + (_seconds/120);
}
public function get minutesDegree():Number {
return (_minutes * 6 - 90) + (_seconds / 10);
}
public function get secondsDegree():Number {
return _seconds*6 - 90;
}
}
}

以下がその使用例。ドキュメントクラス 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+"時になったよ。");
}
}
}
このエントリーをはてなブックマークに追加
はてなブックマーク - Flashで時計作る時に – 「TeraClock」ライブラリ作りました

Comments:5

カヲル 08-09-03 (水) 1:38

teraさんのzigoengineのスクリーンキャストに感動してFlashのライブラリデビューしました。
そして今回、クラスを使うということ、にまたまた感動しました。
今、AS3への移行を進めています。
いつも教えていただいてばかりなので、早く、少しでもお返しできるようになりたいと、
今夜あらためて決意しました。

これからも楽しみにしています。

tera 08-09-06 (土) 11:45

>カヲル様
コメントありがとうございます。
FuseKit は僕の中でも「Flash がさらに楽しくなったきっかけ」の1つです。
世の中ではどんどん新しいテクニック・便利そうな Tips が登場してくるので、みっちり勉強できる時間が欲しいですねぇ。
今後ともよろしくお願いいたします。

uranodai 08-09-07 (日) 3:54

ステキクラスをありがとうございます。AS2に勝手移植してみました。http://www.libspark.org/svn/as2/TeraClock/
これでchumbyでもだいじょぶですw

tera 08-09-07 (日) 4:21

>uranodai様
うひょー!ありがとうございますー!
uranodaiさん&Spark万歳ですw。
大阪てら子も時計ですので、その辺も含めてまたエントリで紹介させてもらいますねー。

れん 08-09-08 (月) 14:18

まいどまいどありがとうございます。

大阪teracoの方で「作る」と言ったものの「実業務との時間配分」に難儀しそうです。w

teraさん&uranodaiさんのクラス、思いっきり参考&アテにさせて頂きます。m(_ _)m

Comment Form
Remember personal info

Trackbacks:4

Trackback URL for this entry
http://www.trick7.com/blog/2008/09/02-074335.php/trackback
Listed below are links to weblogs that reference
Flashで時計作る時に – 「TeraClock」ライブラリ作りました from trick7
pingback from « 大阪てらこ17 « trace 09-01-26 (月) 13:00

[…] 東京てらこのテーマが時計ってことで、それに相乗りした形で大阪でも時計がテーマに。 しかも大阪がパクったのに大阪のほうが先に開催。 そもそも、yugopさんの展覧会が開かれて、それが時計にまつわるネタが多く、 それに触発されたりして、trick7のteraさんが自作のライブラリ、TeraClockを作られて、それを使った色々なものが見たい!ってのもあって、時計がテーマ、となったようです。(割愛、推察あり) […]

pingback from papervision3dのyaw,pitch,roll 09-02-10 (火) 3:02

[…] tweenerとteraclock、papervsion3Dを使っています。 […]

pingback from チマナコィズムシィステム - お腹時計 09-05-07 (木) 2:03

[…] 東京てら子 5 – Flashで時計大会には参加できないけど、時計を作ってみましたよ。ご覧の通り完成度は低いけど…。いつも一方的にお世話になっているtrick7さんのTeraClockを使わせて頂きました。時計が簡単に作れるゴキゲンなライブラリです! […]

pingback from 大阪てら子17 には参加できなかったけどTeraClock使って時計は用意しといたよ - sakotsu inspire blog / サコツインスパイア ブログ 12-07-11 (水) 4:45

[…] 今回のお題が時計ということでしたので、AS3ライブラリ『TeraClock』を使わせていただきましたよ。ありがとうございました! 僕のようなAS3ビギナーがライブラリの使い方に慣れるためのすごい良い教材でもありますので、みなさまも是非! […]

Return to page top