Flash 時計を作る


Flash で、ActionScript を使用して現在時刻を表示する時計を作ることが出来ます。
ここでの「現在時刻」とはその Flash を再生しているコンピュータに設定されている時刻のことで、
コンピュータの時刻の設定がずれていた場合、 Flash で表示する時刻も同じように影響されるので注意してください。
「ActionScript で変数の内容をテキストで表示する」ことができれば簡単に作れます。
ここではパソコン(スマートフォン含む)向けに動作する時計(SWF6〜8)と、携帯電話端末(ガラケー等のFlash Lite向け。スマートフォンは除く)向けに動作する時計(SWF4)それぞれの作り方を解説します。

▼パソコン向けのFlash時計  ▼携帯電話端末向けのFlash時計


■パソコン用のFlash時計

ActionScript で現在時刻を取得するには、まず「デートオブジェクトDateObject)」というものを作成します。

n_date = new Date();

ここでは例として、「n_date」という変数にデートオブジェクトを作成します。実際には自分の好きな名前をつけてください。
デートオブジェクトを作成した「n_date」には、次のようなデートオブジェクトに設定された瞬間の時刻の情報が入っています。

n_date.getFullYear()
n_date.getMonth()
n_date.getDate()
n_date.getDay()
n_date.getHours()
n_date.getMinutes()
n_date.getSeconds()
n_date.getMilliseconds()
現在の西暦(4桁)
現在の月から -1 された数値(0〜11)
現在の日付(1〜31)
現在の曜日(0〜6 = 日〜土)
現在の時(0〜23)
現在の分(0〜59)
現在の秒(0〜59)
現在のミリ秒(0〜999)

getMonth()のみ 0 からカウントするため、実際の月よりも -1 された数値が入っています。あらかじめ +1 してから表示してください。
デートオブジェクトに入っている情報は、「デートオブジェクトを設定した瞬間の時刻」なので、
常に最新の時刻を取得するには、デートオブジェクトを何度も設定して時刻データを更新しなければいけません。


デジタル時計を作る場合、以下のように時刻の情報を変数に代入して表示します。ここでは例としてnow_timeという変数にすべての情報をまとめて代入しています。

n_date = new Date();    //オブジェクトの作成
now_time = "";          //表示用変数の初期化
week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];    //曜日用配列の作成
now_time = n_date.getFullYear() + "/";     //西暦
now_time += (n_date.getMonth() + 1)+ "/";  //月
now_time += n_date.getDate() + " (";       //日付
now_time += week[n_date.getDay()] + ") ";  //曜日
now_time += n_date.getHours() + ":";       //時間
now_time += n_date.getMinutes() + ":";     //分
now_time += n_date.getSeconds();           //秒

曜日の表示について
getDay()は「」の曜日を、
0123456」のように数字で返すので、
曜日用の配列変数を作成して、数字に見合った曜日名をnow_timeに代入するようにしています。
配列は、week[0] ⇒ Sunweek[1] ⇒ Mon、…となっているので、[ ]の中の数値をgetDay()で指定することでこれを実現できます。
詳しくは配列の使い方について調べてみてください。

上記の処理で現在時刻を取得することができるのですが、
常に現在時刻を表示し続けるためにこの処理を毎フレーム行って時計として機能するようにします。
例えばクリップアクションでonClipEvent(enterFrame)を使用する方法などがあります。

それでは実際に作ってみましょう。まず ParaFla! / Suzuka で新しくスプライトとテキストを作成します。

● ParaFla! の場合は、テキストの「ファイルのプロパティ」を開き、「変数名」に「now_time」と入力して「OK」を押します。
スプライトを「イベントに追加」したあと「スプライトを編集」を押して、スプライトの中に先ほどのテキストを「イベントに追加」します。
メインイベントに戻り、スプライトの「イベントのプロパティ」を開いたら、「スクリプトを編集」を押してください。

● Suzuka の場合は、テキストの「テキストのプロパティ」を開き、フォントを「_ゴシック」にして「変数名」のところに「now_time」と入力して「OK」を押します。
スプライトを「レイヤーに追加」したあと、「編集」を押してスプライトの編集画面に移り、スプライトの中に先ほどのテキストを「レイヤーに追加」します。
メインイベントに戻り、スプライトの「キーフレーム編集枠」にある「スクリプトを編集」を押してください。

スクリプトの編集画面になったら、スクリプトエディタに以下を書き込みます。

onClipEvent(enterFrame){
        n_date = new Date();
        now_time = "";
        week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        now_time = n_date.getFullYear() + "/";
        now_time += (n_date.getMonth() + 1)+ "/";
        now_time += n_date.getDate() + " (";
        now_time += week[n_date.getDay()] + ") ";
        now_time += n_date.getHours() + ":";
        now_time += n_date.getMinutes() + ":";
        now_time += n_date.getSeconds();
}

「プレビュー」してみてください。デジタル時計のように表示されていますか?

2007/2/15 (Thu) 23:10:43

こんな感じで表示されるはずです。
表示されない場合は、テキストの「変数名」のところに「now_time」と入力されているか、
スプライトの中にテキストを配置しているか、スプライトからメインイベントに戻ってからプレビューしているか、を確認してみてください。


アナログ時計を作りたい場合は、時刻にあわせて針の絵を回転させるような ActionScript を記述します。
時刻を取得するところまでは同じですが、時、分、秒を以下のようにそれぞれ別の変数に代入すると処理しやすくなります。

n_date = new Date();
h_time = n_date.getHours();
m_time = n_date.getMinutes();
s_time = n_date.getSeconds();

まず、ペイントソフトなどで針の絵(秒針、長針、短針の3種類)を作ります。
[時計の針のサンプル画像]
このように、すべて上向きにデザインするとスクリプトで制御しやすいです。

● ParaFla! の場合は、スプライトを3つ新規作成して「イベントに追加」、3枚の絵をそれぞれのスプライトに入れます。
絵をスプライトに入れたら、それぞれ絵の「イベントのプロパティ」を開き、
「中心位置」の欄に回転の軸にしたい座標を入力します。
このとき、描画位置の X 、 Y 座標は 0 になるようにしてください。

3枚とも設定し終わったら、メインイベントに戻ってスプライトの「イベントのプロパティ」を開き、
秒針を入れたスプライトに「sec_t」、分針を入れたスプライトに「minu_t」、
時針を入れたスプライトに「hour_t」というインスタンス名を付けてください。
また、それぞれ3つのスプライトに描画位置のX、Y座標を入力しておきます。
Flashのサイズが 320 * 320 なら、スプライトの座標は 160 * 160 あたりにしておくといいと思います。
3つのスプライトともX、Y座標は同じ値を入力しておいてください。すると、針がこのX、Y座標を基準に回転するようになります。

さらに、3つのスプライトすべて「固定画面」に設定し、
深度を「hour_t」⇒「0」、「minu_t」⇒「1」、「sec_t」⇒「2」というように設定したら、
3つのスプライトの一番下に「アクションを追加」⇒「<スクリプト>」でフレームアクションを作成します。

● Suzuka の場合は、スプライトを3つ新規作成して「レイヤーに追加」、3枚の絵をそれぞれのスプライトに入れます。
絵をスプライトに入れたら、それぞれ絵の「キーフレーム編集枠」で、
「制御点」の欄に回転の軸にしたい座標を入力します。
このとき、X、Y座標は 0 になるようにしてください。

3枚とも設定し終わったら、メインイベントに戻ってスプライトの「レイヤーのプロパティ」を開き、
秒針を入れたスプライトに「sec_t」、分針を入れたスプライトに「minu_t」、
時針を入れたスプライトに「hour_t」というインスタンス名を付けてください。
また、それぞれ3つのスプライトに「キーフレーム編集枠」からX、Y座標を設定しておきます。
Flashのサイズが 320 * 320 なら、スプライトの座標は 160 * 160 あたりにしておくといいと思います。
3つのスプライトともX、Y座標は同じ値を入力しておいてください。すると、針がこのX、Y座標を基準に回転するようになります。

レイヤーリストでスプライトの順番が上から順に「sec_t」、「minu_t」、「hour_t」となるように配置したら、
その下に「アクションレイヤーを挿入」でフレームアクションを作成します。

フレームアクションを作成できたら、スクリプトエディタに以下を書き込みます。

onEnterFrame = function(){
        n_date = new Date();
        //デートオブジェクト作成
        _root.hour_t._rotation = n_date.getHours() * 30 + n_date.getMinutes() / 2;
        //時針を回転
        _root.minu_t._rotation = n_date.getMinutes() * 6;
        //分針を回転
        _root.sec_t._rotation = n_date.getSeconds() * 6;
        //秒針を回転
};

メインイベントに戻りプレビューすれば針がアナログ時計のように動いているはずです。
動いていない場合は、スプライトにインスタンス名が設定されているか、スプライトの中に針の絵が入っているか、などを確認してください。


上に示したスクリプトで針は時計のように回転しますが、改良を加えることで針の動きを滑らかにすることができます。

_root.hour_t._rotation = n_date.getHours() * 30 + n_date.getMinutes() / 2;

時針を動かす部分には上記のように太字で示した部分の処理がありますが、これは時針の動きを滑らかにするためのものです。
時計の文字盤は12分割なので、360÷12=30 となり、時針は1時間当たり30°回転すればよいことになります。
よって時針の現在の回転角度は (現在の時×30)+(現在の分÷2) となり、上式のようになります。
この仕組みを分針と秒針にも導入してみます。

onEnterFrame = function(){
        n_date = new Date();
        //デートオブジェクト作成
        _root.hour_t._rotation = n_date.getHours() * 30 + n_date.getMinutes() / 2;
        //時針を回転
        _root.minu_t._rotation = n_date.getMinutes() * 6 + n_date.getSeconds() / 10;
        //分針を回転
        _root.sec_t._rotation = n_date.getSeconds() * 6 + n_date.getMilliseconds() / 180;
        //秒針を回転
};

これで時針、分針、秒針のすべてが滑らかに回転するようになります。


以下は、時計のサンプルです。

Flashを表示できません。

Flashを表示できません。

通常の動作

滑らかな動作

Flash時計サンプルソースのダウンロード


■携帯電話端末用のFlash時計

携帯電話端末(Flash Lite)で時刻を取得するには、「FSCommand2」コマンドを使います。
ただし、FSCommand2はパソコンでは動作しないので、
動作の確認は携帯電話で行うか、パソコンで携帯端末をシミュレートして表示できるブラウザを使う必要があります。

時刻を取得するだけならば、以下のコマンドを使うのが簡単です。

FSCommand2("GetLocaleTime", "変数名");

「変数名」の部分に時刻を代入したい変数名を入力すると、その変数に時、分、秒が代入されます。

11:03:18

変数に代入されるデータは上記のようになっています。


時刻の情報を個別に取得する場合も FSCommand2 を使います。

FSCommand2("GetDateYear")
FSCommand2("GetDateMonth")
FSCommand2("GetDateDay")
FSCommand2("GetDateWeekday")
FSCommand2("GetTimeHours")
FSCommand2("GetTimeMinutes")
FSCommand2("GetTimeSeconds")
現在の西暦(4桁)
現在の月(1〜12)
現在の日付(1〜31)
現在の曜日(0〜6)
現在の時刻(0〜23)
現在の分(0〜59)
現在の秒(0〜59)

FSCommand2 のGetDateMonthはデートオブジェクトのものとは異なり、表示の際に +1 する必要はありません。
曜日は数字で返されるので、表示する際には文字に置換する必要があります。


デジタル時計を作る場合、上記のコマンドで情報を取得して表示します。
ただし、SWF4 の ActionScript 構文に従って記述する必要があるので注意が必要です。

now_time = "";
//変数の初期化
("week" & "0") = "Sun";
("week" & "1") = "Mon";
("week" & "2") = "Tue";
("week" & "3") = "Wed";
("week" & "4") = "Thu";
("week" & "5") = "Fri";
("week" & "6") = "Sat";
//曜日用の擬似配列作成
now_time_yr = FSCommand2("GetDateYear") & "/";
now_time = now_time & now_time_yr;
//西暦
now_time_mth = FSCommand2("GetDateMonth") & "/";
now_time = now_time & now_time_mth;
//月
now_time_dy = FSCommand2("GetDateDay") & " (";
now_time = now_time & now_time_dy;
//日付
wd = FSCommand2("GetDateWeekday");
now_time = now_time & valueOf("week" & wd) & ") ";
//曜日
now_time_h = FSCommand2("GetTimeHours") & ":";
now_time = now_time & now_time_h;
//時刻
now_time_m = FSCommand2("GetTimeMinutes") & ":";
now_time = now_time & now_time_m;
//分
now_time_s = FSCommand2("GetTimeSeconds");
now_time = now_time & now_time_s;
//秒

スクリプト部分は上記のようになります。
デジタル時計を作成するには、まず「プロジェクトのプロパティ」の「SWFバージョン」で「SWF4」を選択します。

● ParaFla! の場合、次にテキストを新規作成して「変数名」に「now_time」と入力し、「自動サイズ」のチェックを外して幅と高さに適当な値(「300」など)を入力します。(SWF4 ではテキストの「自動サイズ」が使用できないため。)
テキストを「イベントに追加」したら、イベント欄の2段目に「アクションを追加」⇒「<スクリプト>」でフレームアクションを作成し、上に示したスクリプトを書き込みます。

● Suzuka の場合、次にテキストを新規作成してフォントを「_ゴシック」にし、変数名に「now_time」と入力し、「自動サイズ」のチェックを外して幅と高さに適当な値(「300」など)を入力します。(SWF4 ではテキストの「自動サイズ」が使用できないため。)
テキストを「レイヤーに追加」したら、次に「アクションレイヤーを挿入」でフレームアクションを作成し、上に示したスクリプトを書き込みます。

「SWFファイル生成」で swf ファイルを作成し、携帯電話に送信してFlashを再生します。
携帯電話に swf ファイルを送信する方法は、
 1. メールに添付して送信する
 2. インターネットにアップロードし、携帯電話のブラウザでアクセスする
などの方法があります。docomo の携帯の場合、1の方法は使用できないようです。

2007/2/18 (Sun) 12:38:23

正常に動作すればこのように表示されます。
表示されても時刻が更新されない場合はスクリプトの処理が繰り返されていない可能性があるので、「ラベルジャンプ」や「フレームジャンプ」を使ってスクリプトが何度も実行されるようにする必要があります。


携帯電話向けのアナログ時計を作成する場合、上記デジタル時計と同様の方法で時刻を取得し、時刻に合わせて針の画像を回転させるようにします。

針の画像を作成してスプライトに追加し、フレームアクションを挿入するところまではパソコン向けのアナログ時計の作成方法と同じです。ページ上部のパソコン向けのアナログ時計の作成手順を参照してください。
次に、「プロジェクトのプロパティ」から「SWFバージョン」で「SWF4」を選択します。
そして、挿入したフレームアクションに以下のスクリプトを書き込みます。

/hour_t.rotation = FSCommand2("GetTimeHours") * 30 + FSCommand2("GetTimeMinutes") / 2;
//時針を回転
/minu_t.rotation = FSCommand2("GetTimeMinutes") * 6;
//分針を回転
/sec_t.rotation = FSCommand2("GetTimeSeconds") * 6;
//秒針を回転
/hour_t.xscale = 100;
/minu_t.xscale = 100;
/sec_t.xscale = 100;
/hour_t.yscale = 100;
/minu_t.yscale = 100;
/sec_t.yscale = 100;
//画像が縮むのを防ぐ

SWF4では計算精度の関係で rotarion で画像を回転させたときに画像のサイズが小さくなっていってしまうので、最後の6行で小さくなってしまうのを防いでいます。
最後に「SWFファイル生成」で swf を作成し、携帯電話で再生します。針がアナログ時計のように回転していれば成功です。

針を滑らかに動作させるようにするにはパソコン向けアナログ時計と同じ仕組みを導入すれば実現できます。
ただし、秒針を滑らかに回転させるためには少し工夫が必要で、具体的には以下のようになります。

fps = 20;
//FPSの設定
/hour_t.rotation = FSCommand2("GetTimeHours") * 30 + FSCommand2("GetTimeMinutes") / 2;
//時針を回転
/minu_t.rotation = FSCommand2("GetTimeMinutes") * 6 + FSCommand2("GetTimeSeconds") / 10;
//分針を回転
t_f = 1 / fps;
if(FSCommand2("GetTimeSeconds") != t_sec){
        cnt = 0;
        t_sec = FSCommand2("GetTimeSeconds");
}else{
        cnt = cnt + 1;
}
millisec = t_f * cnt;
/sec_t.rotation = int((FSCommand2("GetTimeSeconds") + millisec) * 6);
//秒針を回転
/hour_t.xscale = 100;
/minu_t.xscale = 100;
/sec_t.xscale = 100;
/hour_t.yscale = 100;
/minu_t.yscale = 100;
/sec_t.yscale = 100;

1行目にfpsという変数がありますが、これには Flash に設定した FPS と同じ値を入力してください。
秒針の滑らかな処理にはミリ秒の値が必要ですが FSCommand2 にはミリ秒を取得するコマンドが用意されていないため、FPS の値から1フレーム当たりの回転すべき角度を計算して、擬似的に滑らかな回転を実現しています。

SWF4 のミリ秒を計算している部分は his さんに教えていただきました。ありがとうございます。


以下は、SWF4 の時計のサンプルです(パソコンで表示しても動作しません)。

通常の動作

滑らかな動作

携帯端末用Flash時計サンプルソースのダウンロード


トップページに戻る