『 続・Eseclockを改造しました 』
2009 年 4 月 10 日前回のエントリに引き続き、今回もEseclockについてです。
テーマはずばり
『改造版Eseclockの使い方』
色々やり方はあると思いますが、ドキュメントクラスにEseclockを継承させる方法を紹介します。誰も使わないかも知れない(ていうかむしろいつ使えるの?)なライブラリをこつこつ紹介するという、なんともストイックな企画です。
0.ライブラリをダウンロードする
SparkProjectはSubversion(以下SVN)というファイル管理ソフトによって全てのプロジェクトが管理されています。まず、このSVNから手元にライブラリをダウンロードする必要があります。詳しくはzyass_takさんのこちらの記事がわかりやすいので参考にしてください。
さて、無事にライブラリを落とし終わって中身をのぞいてみると、いくつものフォルダがあると思います。とりあえず、http://www.libspark.org/svn/をチェックアウトしたものとして、as3\Eseclock\branches\alumican\srcフォルダの中にあるcaurina、org、jpフォルダをコピーして、自分のflaファイルのあるフォルダにペーストします。別階層にペーストする場合には、ライブラリフォルダまでのクラスパスを適宜通しておいてください(CS3の場合は[パブリッシュ設定]->ActionScriptのバージョンの隣の[設定]->クラスパス)。これで準備は完了です。おそらく.svnという隠しフォルダもペーストされたかと思いますが、これは削除していただいて構いません。なお、サンプルはソースコード含めCS3形式でas3\Eseclock\branches\alumican\samplesフォルダに入っています。
1.とりあえず動かしてみる
何はともあれ、ドキュメントクラスを作ります。今回はMain.asという名前のクラスを作りました。MainクラスにEseclockを継承させているだけです。サンプルのソースコードはsample\01に入っています。
package {
import org.libspark.eseclock.Eseclock;
//Eseclockクラスを継承させる
public class Main extends Eseclock {
public function Main():void {
}
}
}
>>Sample
ドキュメントクラスとして設定するのを忘れずにパブリッシュすると、白黒の時計の合間に水玉が表示される何とも味気のないUNIQLOCKもどきができるかと思います。これがプレーンな状態ですが、この時点で時計部分の大きさを保ったまま自動でステージにフィットするようになっています。これを元に拡張していきます。
2.色を変えてみる
白黒だとつまらないので、ランダムな色のカラフルな時計にします。本家UNIQLOCKを真似して、白黒からランダム色と白色に変えます。Mainクラスのコンストラクタ内で、親クラス、つまりEseclockのコンストラクタを呼び出します。サンプルのソースコードはsample\02に入っています。
package {
import org.libspark.eseclock.Eseclock;
public class Main extends Eseclock {
public function Main():void {
//1番目と2番目の引数で色を指定する
super(uint(Math.random() * 0xffffff), 0xffffff);
}
}
}
>>Sample
最初の引数と2番目の引数で、テキストと背景の2色を指定できます。ここでは、最初の引数で0から0xffffffまでのランダムな数値を渡し、2番目の引数で固定の白色を渡しています。ちなみに、色はコンストラクタで指定できる他にも、後からcolor1、color2プロパティで変えることができます。
ちょっと華やかなEseclockができました。
3.好きな動画を時計の合間に表示する
やはり、UNIQLOCKもどきなるもの、時計の合間には水玉ではなく好きなコンテンツを表示したいです。改造版Eseclockでは、_createContentメソッドをオーバーライドすることでこれを実現できます。_createContentメソッドはコンテンツが表示される直前に毎回呼ばれ、2つの引数wとhを受け取ってDisplayObjectを返します。要は、wとhのサイズ作ったビジュアルをreturnすれば次の瞬間それが表示されるというわけです。サンプルでは、FLVPlaybackコンポーネントを使って動画を再生してみます。動画を何本も用意するのは面倒なので、1本の動画をランダムにシークさせて再生するようにします。
手順は少し複雑です。まず、動画を読み込むまで時間がかかるので、Eseclockを停止しておきます。そして、動画の読み込みが終わった後に、Eseclockをスタートさせます。Eseclock実行中、_createContentが呼ばれる度に動画をランダムにシークして再生させます。そして動画から時計に戻る瞬間に、動画がバックグラウンドで再生され続けないようにFLVPlaybackを一時停止します。
ひとつずつ考えていきます。
>Eseclockを停止しておきます。
EseclockはデフォルトでaddChildされた瞬間にスタートしますが、コンストラクタの第6引数(autoPlay)をfalseに設定することで自動再生させないようにできます。この場合、任意のタイミングでstartメソッドを呼び出すことでEseclockをスタートさせられます。
>Eseclock実行中、_createContentが呼ばれる度に動画をランダムにシークして再生させます。
_createContentメソッド内で、FLVPlaybackをseekしてplayすればいいかと思います。
>動画から時計に戻る瞬間に、動画がバックグラウンドで再生され続けられないように一時停止します。
改造版Eseclockでは、_createContentメソッドの他にもいくつかオーバーライド可能なメソッドが定義されています。その一つが_removeContentで、このメソッドはコンテンツが完全に隠れる瞬間に呼び出されます。このメソッドをオーバーライドして、FLVPlaybackをpauseなどすれば良さそうです。
以上をふまえたサンプルはこちらです。swfファイルと同階層にmovie.flvを置いておいてください。flv含めソースコードはsample\03に入っています。
package {
import fl.video.FLVPlayback;
import fl.video.VideoEvent;
import fl.video.VideoScaleMode;
import flash.display.DisplayObject;
import flash.events.Event;
import org.libspark.eseclock.Eseclock;
public class Main extends Eseclock {
//時計の合間に表示するFLVを再生させるFLVPlayback
private var _flvp:FLVPlayback;
public function Main():void {
//自動スタートさせないように第6引数(autoPlay)をfalseにしておく。第3、第4、第5引数はとりあえずデフォルトのまま
super(uint(Math.random() * 0xffffff), 0xffffff, 640, 320, true, false);
addEventListener(Event.ADDED_TO_STAGE, _initialize);
}
//addChildされるのを待ってから初期化をおこなう
private function _initialize(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, _initialize);
//FLVの読み込み
_flvp = new FLVPlayback();
_flvp.autoPlay = false;
_flvp.autoRewind = false;
_flvp.scaleMode = VideoScaleMode.EXACT_FIT;
_flvp.addEventListener(VideoEvent.READY, _flvpRedyHandler);
_flvp.load("movie.flv");
}
//動画の再生準備完了時に呼び出されるイベントハンドラ
private function _flvpRedyHandler(e:VideoEvent):void {
_flvp.removeEventListener(VideoEvent.READY, _flvpRedyHandler);
//Eseclockスタート
start();
}
//コンテンツが表示される直前に呼び出されるメソッド
override protected function _createContent(w:Number, h:Number):DisplayObject {
//再生開始位置をランダムで選択(動画が途中で終わらないように, 6秒ほど余裕を持たせておく)
var head:uint = uint(Math.random() * (_flvp.totalTime - 6));
//EseclockのサイズにFLVPlaybackをフィットさせる
_flvp.width = w;
_flvp.height = h;
//FLVPlaybackを再生する
_flvp.seek(head);
_flvp.play();
return _flvp;
}
//コンテンツが完全に隠れる直前に呼び出されるメソッド
override protected function _removeContent(content:DisplayObject):void {
//動画がが裏側で再生され続けないように一時停止処理をかけておく
FLVPlayback(content).pause();
}
}
}
>>Sample
ちょっと長いですが、大半は動画の読み込み処理のコードです。大事なのはコンストラクタのautoPlay、startメソッド、_createContentメソッド、_removeContentメソッドです。ちなみに_removeContentでは引数として表示中のコンテンツを受け取れます。サンプルではこのcontent引数を使ってFLVPlaybackを停止させていますが、この例ではFLVPlaybackをインスタンス変数_flvpとして保持しているので、_flvp.pause();で全く問題ありません。
だんだんそれっぽくなってきました。
4.ピッピッピッピッポーン音を付ける
よりそれらしくするために、時報の音(ピッ音とポーン音)を付けたいと思います。どうやらピッ音は秒数の一の位が0以外の時に鳴って、ポーン音は秒数の一の位が0の時になるようです。改造版Eseclockでは、こういった毎秒の処理を簡単におこなうために_tickメソッドをオーバーライドできるようになっています。_tickメソッドは毎秒呼び出され、引数として時分秒を表す3つの引数h、m、sを受け取ることができます。サンプルでは、リンケージされた2つのライブラリのサウンドオブジェクトSound1(ピッ音)とSound2(ポーン音)を使って時報の音を鳴らします。
実際のコードはこちらです。サウンドデータ含めソースコードはsample\01に入っています。
package {
import fl.video.FLVPlayback;
import fl.video.VideoEvent;
import fl.video.VideoScaleMode;
import flash.display.DisplayObject;
import flash.events.Event;
import org.libspark.eseclock.Eseclock;
public class Main extends Eseclock {
private var _flvp:FLVPlayback;
private var _sound1:Sound1; //ピッ音
private var _sound2:Sound2; //ポーン音
public function Main():void {
super(uint(Math.random() * 0xffffff), 0xffffff, 640, 320, true, false);
addEventListener(Event.ADDED_TO_STAGE, _initialize);
}
private function _initialize(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, _initialize);
_flvp = new FLVPlayback();
_flvp.autoPlay = false;
_flvp.autoRewind = false;
_flvp.scaleMode = VideoScaleMode.EXACT_FIT;
_flvp.addEventListener(VideoEvent.READY, _flvpRedyHandler);
_flvp.load("movie.flv");
//ライブラリのサウンドを割り当てる
_sound1 = new Sound1();
_sound2 = new Sound2();
}
private function _flvpRedyHandler(e:VideoEvent):void {
_flvp.removeEventListener(VideoEvent.READY, _flvpRedyHandler);
start();
}
override protected function _createContent(w:Number, h:Number):DisplayObject {
var head:uint = uint(Math.random() * (_flvp.totalTime - 6));
_flvp.width = w;
_flvp.height = h;
_flvp.seek(head);
_flvp.play();
return _flvp;
}
override protected function _removeContent(content:DisplayObject):void {
_flvp.pause();
}
//_tickメソッドは毎秒呼び出される
override protected function _tick(h:uint, m:uint, s:uint):void {
if (s % 10 == 0) {
//秒数の一の位が0ならポーン音を鳴らす
_sound2.play();
} else {
//それ以外ならポーン音を鳴らす
_sound1.play();
}
}
}
}
>>Sample
だいぶ良い感じに仕上がってきました。
さらに、コンテンツが表示されるときには音量がフェードインし、コンテンツが隠れるときには音量がフェードアウトする演出を、TweenerのSoundShortcutsを使って実装したサンプルを置いておきます。ソースコードはsample\05フォルダに入っています。
>>Sample
今回は必要ないのですが、ついでに紹介しておくと、オーバーライド可能なメソッドはもう1つあります。それは、コンテンツを表示中にEseclockがリサイズされたときにだけ呼び出される_resizeContentメソッドです。このメソッドでは3つの引数content、w、hを受け取れて、それぞれ表示中のコンテンツ、リサイズ後のEsclockの幅、リサイズ後のEseclockの高さを表しています。_resizeContentメソッドはデフォルトで
content.width = w;
content.height = h;
を実行するため、今回のようにFLVPlaybackを縦横比無視でEseclockのサイズにフィットさせるぶんには特にオーバーライドする必要がありません。しかし、コンテンツの縦横比を無視したくない場合などには適宜オーバーライドする必要があるかと思います。
今回はここまでです。
次回は、時計表示部分と時計下のテキスト表示部分を好きなフォーマットに組み替える方法を紹介します。
みんなでおもしろいEseclock作品を作ると楽しそうですね~(o’c_,`人)・:*:・
