- 2008-09-02 (火)
- action script | video_tutorial
簡単に 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+"時になったよ。");
}
}
}
- Newer: 東京てら子 5 - Flashで時計大会
- Older: 坂本龍一さんにインタラクションの理想を見た
Comment:5
- カヲル 2008-09-03 (水) 01:38
-
teraさんのzigoengineのスクリーンキャストに感動してFlashのライブラリデビューしました。
そして今回、クラスを使うということ、にまたまた感動しました。
今、AS3への移行を進めています。
いつも教えていただいてばかりなので、早く、少しでもお返しできるようになりたいと、
今夜あらためて決意しました。これからも楽しみにしています。
- tera 2008-09-06 (土) 11:45
-
>カヲル様
コメントありがとうございます。
FuseKit は僕の中でも「Flash がさらに楽しくなったきっかけ」の1つです。
世の中ではどんどん新しいテクニック・便利そうな Tips が登場してくるので、みっちり勉強できる時間が欲しいですねぇ。
今後ともよろしくお願いいたします。 - uranodai 2008-09-07 (日) 03:54
-
ステキクラスをありがとうございます。AS2に勝手移植してみました。http://www.libspark.org/svn/as2/TeraClock/
これでchumbyでもだいじょぶですw - tera 2008-09-07 (日) 04:21
-
>uranodai様
うひょー!ありがとうございますー!
uranodaiさん&Spark万歳ですw。
大阪てら子も時計ですので、その辺も含めてまたエントリで紹介させてもらいますねー。 - れん 2008-09-08 (月) 14:18
-
まいどまいどありがとうございます。
大阪teracoの方で「作る」と言ったものの「実業務との時間配分」に難儀しそうです。w
teraさん&uranodaiさんのクラス、思いっきり参考&アテにさせて頂きます。m(_ _)m
Trackback:0
- TrackBack URL for this entry
- http://www.trick7.com/blog/mt-tb.cgi/783
- Listed below are links to weblogs that reference
- Flashで時計作る時に - 「TeraClock」ライブラリ作りました from trick7.com blog











