ビヘイビアのインスタンスとメッセージ(2)
こちらはビヘイビアに関してご理解いただくための情報です。「デジタルビデオのコントロール」を例にとってビヘイビアの利用方法をご確認ください。(ただし、文中のLINGOはDirector7Jからご利用いただけるドットシンタックスで記載されております。Director6.xをご利用の方はご注意ください。)
| 1 | はじめに デジタルビデオがスプライト1にあるとします。再生ボタンのスクリプトはどのように書くでしょうか。 -- [再生ボタン] on mouseUp sprite(1).movieRate = 1 end ボタンは他にも、停止/巻戻といったものが必要になるでしょう。それらのスクリプトを書いたあとで、デジタルビデオのスプライト番号が変更になったらどうでしょう。あるいは、再生/停止をひとつのボタンで行う仕様に変わるかもしれません。スクリプトをひとつひとつ直す手間も大変ですが、修正が必要なスクリプトをもれなく拾い出すことにも神経を使います。 ビヘイビアの特性を活用すれば、別のやり方が可能です。発想を転換して、デジタルビデオのコントロールはすべてひとつにまとめ、ボタンからはそのビヘイビアに単純なメッセージを送るだけという手法です。これは丁度リモコンでAV機器を操作するようなイメージです。リモコンのボタンを押して送られるのは、単なる信号です。その信号に対応してどういう動作をするかは、本体の回路が判断するわけです。 |
| 2 | デジタルビデオにビヘイビアを設定する ビヘイビアは、デジタルビデオのスプライトに貼りつけることにします。 -- [デジタルビデオの再生用ハンドラ] on xPlay me sprite(me.spriteNum).movieRate = 1 end 'xPlay'というのはカスタムハンドラです。どんな名前でも構いませんが、'play'はコマンドとして存在するので避けましょう。また、何らかのかたちでカスタムハンドラであることがわかる決まりごとをつくっておくと、スクリプトが(自分自身にとっても)わかりやすくなります。ここでは、カスタムハンドラは小文字のxで始めることにします。 ハンドラの後ろにつく'me'は、スプライトに設定された個々のビヘイビア(正確にはビヘイビアのインスタンスです。(technote: dr016876「ビヘイビアのインスタンスとメッセージ(1)」参照)を意味します。ひとつのスコアスクリプトとしてのビヘイビア (スクリプトキャストメンバー)は、いくつものスプライトに設定することができます。けれど、マウスボタンを押したとか、ロールオーバーしたなどのイベントは、個々のスプライトのビヘイビア(インスタンス)ごとに判定されます。'on xPlay me'というのは、そのスプライトに設定された自分のビヘイビア(インスタンス)に 'xPlay'というメッセージが送られたとき実行されるハンドラなのです。 'me.spriteNum'というのも同様で、ビヘイビアを設定したそのスプライトのチャンネル番号を返します。ですから、デジタルビデオがスプライト1にあれば、このハンドラのステートメントは'sprite(1).movieRate = 1'と同じことになります。けれど、スプライトのチャンネルが変更されても、常にそのスプライトを参照するという点が大きく異なります。 Director 7からは、さらにスプライトそのものを変数に格納できるようになりました。'sprite(me.spriteNum)'をひとつの変数、たとえばmySpriteに入れてしまえるのです。そしてビヘイビアには、そのビヘイビア(インスタンス)の中で共通に参照できるプロパティ変数というものがあります。そうするとデジタルビデオコントロールのビヘイビアは、次のように書けます。 -- [デジタルビデオコントロール] property pMySprite on beginSprite me pMySprite = sprite(me.spriteNum) end on xStop me pMySprite.movieRate = 0 end on xPlay me pMySprite.movieRate = 1 end on xRewind me me.xStop() pMySprite.movieTime = 0 end 'pMySprite'が'property'定義されています(プロパティ変数は小文字のpを頭につけることにします)。そして、スプライトの登場とともに呼ばれる'beginSprite'ハンドラで、その設定を行っています。'xRewind'ハンドラの'me.xStop()' は、自分自身 (のインスタンス)に'xStop'メッセージを送っています。これは、'xStop(me)'あるいは'xStop me'と書いても結構です。 |
| 3 | ボタンからデジタルビデオにメッセージを送る ボタンのビヘイビアは、ただメッセージを送るだけです。メッセージは 'sendSprite'コマンドで送ることができます。 -- [再生ボタン] on mouseUp me sendSprite(1, #xPlay) end せっかくビデオコントロールのビヘイビアはチャンネルに依存しなくなっても、ボタンでチャンネルを指定するのではあまり意味がありません。対応策としては、グローバル変数を利用する方法が考えられます。ビデオコントロールビヘイビアの'beginSprite'ハンドラに、たとえば'gVideo = me'のステートメントを追加すれば、再生ボタンのステートメントは'gVideo.xPlay()'とすればよいです。これで'gVideo'に格納したビヘイビア(インスタンス)に'xPlay'メッセージを送ることができます。ビデオスプライトのチャンネルには依存しません。ただ、ボタンも含めた各ビヘイビアに'global'定義が必ず必要になります。 ここではもうひとつ、'actorList'を使う手法をご紹介しましょう('actorList'について、詳しくは『Lingo辞書』またはオンラインヘルプ参照)。'actorList'は特別なリスト形式のグローバル変数と考えればよいでしょう。通常のグローバル変数と異なるのは、(1)'global'宣言を必要とせず、(2)'stepFrame'メッセージを受け取るということです。 -- [デジタルビデオコントロールの変更部分] property pMySprite on beginSprite me pMySprite = sprite(me.spriteNum) (the actorList).append(me) end on endSprite me (the actorList).deleteOne(me) end 'actorList'はリストなので、'append'コマンドを使ってビヘイビア(インスタンス)を加えています。ただ、そのままにしておくと、Directorムービー再生中ずっと'actorList'中に残ったままになります。そこで、'endSprite'ハンドラで、スプライトの消滅とともに'actorList'からビヘイビア(インスタンス)を削除します。 ボタンは、'actorList'に対してメッセージを送ります。このとき使うコマンドが'call'です('call'について詳しくは『Lingo辞書』またはオンラインヘルプ参照)。'call'はビヘイビア(インスタンス)そのものにも、ビヘイビア(インスタンス)のリストにも使用できます。ただし、ビヘイビア(インスタンス)そのものにメッセージを送った場合、対応するハンドラがないと、エラーのアラートが発生しますが、リストの場合には何も起こりません。 -- [再生ボタン] on mouseUp me call(#xPlay, the actorList) end |
| 4 | デジタルビデオが終わったら... デジタルビデオが終わったらどうしましょう。その機能を、ビデオコントロールのビヘイビアに追加します。メニューに戻る、つぎのマーカーに進む、またビデオを最初から繰り返し再生する、などといろいろ考えられます。こういうときは、具体的に実行する機能を特定せず、とにかく終わったというメッセージのみ送ることにしましょう。送り先は自分自身のスプライトが便利です。そうすれば、別のビヘイビアをスプライトに貼り、そのメッセージを受取るハンドラに実行したい機能を書けばよいからです。 -- [デジタルビデオコントロール(完成)] property pMySprite on beginSprite me pMySprite = sprite(me.spriteNum) me.xRewind() (the actorList).append(me) end on endSprite me me.xForget() end on xForget me me.xStop() (the actorList).deleteOne(me) end on xStop me pMySprite.movieRate = 0 end on xPlay me pMySprite.movieRate = 1 end on xRewind me me.xStop() pMySprite.movieTime = 0 end on stepFrame me if pMySprite.movieTime >= pMySprite.duration then me.xFinished() end if end on xFinished me me.xForget() call(#xDoNext, pMySprite.scriptInstanceList) end ビデオの終了は、ビデオスプライトの'movieTime'と'duration'のプロパティを比較して判定します。(technote: dr0044「デジタルビデオの終了を待つ方法」参照)'actorList'は再生ヘッドの移動時に'stepFrame'メッセージを受取りますので、そのハンドラにステートメントを記述します。 ビデオが終了すると、'xFinished'ハンドラが実行されます。ここで、また 'call'コマンドを使って、メッセージ'xDoNext'を送っています。送り先は、自分のスプライトに設定されたビヘイビア(インスタンス)のリスト'scriptInstanceList'です。'sendSprite(me.spriteNum, #xFinished)でも結構です。ビデオスプライトには別のビヘイビアを設定し、その'xDoNext'ハンドラに実行したい処理を書きます。 その他、いくつかのハンドラに若干ステートメントを追加しました。たとえば、ビデオスプライトが表示されたときいきなり再生されないように、'beginSprite'ハンドラで'me.xRewind'を実行しています。再生ボタンが押され、'xPlay'メッセージを受けて再生が始まるという仕様を想定したからです。'xFinished'の最初のステートメント'me.xForget()'は、つぎの作業に移る前の後始末です。ビデオの再生を止め、'actorList'からビヘイビア(インスタンス)を削除しています。この処理は'endSprite'で実行することと同じだったので、これをカスタムハンドラとして取り出し、'endSprite'でもこの同じ'xForget'ハンドラを呼ぶかたちにしました。 このようにビデオに設定したビヘイビアにコントロールを集中させることで、ボタンのビヘイビアをシンプルにできるとともに、機能の追加・変更もしやすくなります。 |
