- ベストアンサー
スクリプトでサウンドのフェードイン、フェードアウト
いつも、ありがとうございます。FLASH8です。 フレームスクリプトからのサウンドのフェードイン、フェードアウト制御についてお聞きします。 ナレーションがスタートしたらBGMをフェードアウト、ナレーションが終わったらBGMをフェードインさせたいのですが、見えないところにムービークリップを作ってムービークリップを読み込む度にサウンドレベルをプラス(マイナス)していき、それをフレームから変数を使って制御する方法で可能でしょうか?また、もっと良い方法があるでしょうか? よろしく、お願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
#1です。 Sound クラスで音を鳴らした時は、再生が終了すると onSoundComplete というイベントが発生します。 このイベントが発生した時に呼ぶ関数を定義しておくと、サウンドの再生終了を待って何かをすることができます。 #1のスクリプトでは、onSoundComplete の中で再度同じ曲を再生することで、BGM を無限ループ再生にしています。 onSoundComplete は Flash Player 6 以降でパブリッシュすると使えます。 ナレーションの終了後に BGM をフェードインさせる処理でも、この onSoundComplete を利用してはいかがでしょう。 わざわざフラグや if 文で判断することなく、ナレーションの終了を待って BGM をフェードインさせることができます。 スクリプトにしてみますと、次のようになります。 一部は省略させていただきます。 省略箇所には#1でご紹介しましたスクリプトを挿入してください。 ナレーションのシンボルのリンケージ識別子を” VOICE ”とします。 (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) ●最初の方のフレームに書くスクリプト /*BGMを鳴らす処理:ここに、#1のBGMを鳴らすスクリプトを書く*/ /*------- 以下を追加 -------*/ //ナレーション用のダミーのムービークリップを作る this.createEmptyMovieClip( "voice_clip" , 1 ); //ナレーションの設定 narr = new Sound( voice_clip ); narr.attachSound( "VOICE" ); //ナレーション終了後にBGMをフェードイン narr.onSoundComplete = function() { //BGMをフェードイン bgm_clip.onEnterFrame = function() { //ボリュームを徐々に上げる bgm_vol += fade_spd; //100になったら終了 if( bgm_vol >= 100 ) { bgm_vol = 100; delete bgm_clip.onEnterFrame; } //ボリュームを設定 snd.setVolume( bgm_vol ); } }; ●ナレーションを再生するフレームに書くスクリプト //BGMをフェードアウト bgm_clip.onEnterFrame = function() { /*ここに、フェードアウトの処理を書く*/ }; //ナレーションを再生 narr.start(); スクリプトは以上です。 attachSound で Sound オブジェクトで使うシンボルを関連付けたとしても、Sound.start を実行するまでは音は鳴りません。 上記のスクリプトでは、まず Sound オブジェクト narr にナレーションのサウンドシンボルを関連付け、再生する準備だけを先に済ませています。 あとはナレーションを入れたい時に narr.start(); を実行すると、ナレーションが再生されます。 今回はとりあえずあるフレームで再生するという作例になっていますが、例えばボタンが押された時や何かのアニメが終わった時などでも構いません。 また、今回は BGM のフェードアウトが始まると同時にナレーションが再生され、クロスフェードのような感じになっています。 何か不都合がありましたら、フェードアウトの処理内で、フェードアウト終了時( bgm_vol の値が 0 以下になった時)に narr.start(); を実行してください。BGM が完全に消えてからナレーションが始まるようになります。 要するに、フェードアウトやナレーションを再生するタイミングの問題です。 このあたりは作品に合わせて適宜変更してください。 ナレーションの後に BGM をフェードインさせる処理は、ナレーションを再生する Sound オブジェクトで onSoundComplete イベントが起きた時に定義されます。 このためのスクリプトは最初の方のフレームで先に定義してありますので、フェードインに関してはフレームに改めてスクリプトを書く必要はありません。 ************************ ナレーションをスクリプトで再生する場合は、音声データが変更された時は、「ライブラリ」パネルのシンボルを選んで「プロパティ」を開き、「更新」か「読み込み...」で簡単に差し替えられます。 シンボルの中身が入れ替わってもリンケージの設定はそのまま残りますから、あまり Flash に詳しい人でなくても差し替えは割と簡単にできると思います。 ただし、スクリプトで鳴らす音は#1にも書きましたようにイベントサウンドですので、画面との同期は保証されません。 画面の進行とナレーションを確実に合わせたい時は、スクリプトで鳴らす方法は不向きです。
その他の回答 (1)
- DPE
- ベストアンサー率85% (666/776)
BGM とナレーションをどのように再生しているかによって違うと思いますが。 ボリュームくらいならムービークリップのタイムラインを使うことでも可能は可能です。 ですが、タイムラインに入れた音はあまり融通が利きません。 ナレーションは画面と合わせるものでしょうからタイムラインの方が簡単だと思いますが、BGM はスクリプトで鳴らす方法がオススメです。 ボリュームは Sound クラスの setVolume メソッドで変更できます。 ただし、setVolume は1つのムービークリップ(タイムライン)につき1つのボリュームしか設定できません。 BGM をどのような形で鳴らすにしても、2種類以上の音のボリュームをそれぞれ操作するには、ムービークリップと Sound クラスのオブジェクトを音の数だけ用意します。 例えばナレーションをメインのタイムラインに既に入れてあるとすると、ナレーションは _root 階層で管理する音ということになります。 BGM を _root の音を制御する Sound オブジェクトで操作すると、BGM のボリュームを下げた時にナレーションのボリュームも小さくなってしまいます。 ナレーションがメインのタイムラインから動かせないのでしたら、BGM の方を移動します。 BGM は、ダミーのムービークリップと、このムービークリップの音を制御する Sound オブジェクトを作って操作すると、BGM のボリュームだけを変更することができます。 ------------------------------------------------------------------ スクリプトで音を鳴らす時は、サウンドシンボルに「リンケージ」の設定が必要です。 サウンドシンボルのように容量の大きなシンボルにリンケージを設定する時は、書き出すフレームにご注意ください。 最初のフレームに書き出すとフレーム1の容量が極端に肥大し、プリロード画面を作っている場合はロード中に再生するアニメがなかなか始まらなくなってしまいます。 このあたりの事情については以前別の質問で説明しましたので、よろしければご参考になさってください。 #3の前半で説明しております。 ・しばらく真っ白な画面になってしまいます。 http://okwave.jp/kotaeru.php3?q=1505484 リンケージの設定方法やリンケージ絡みの問題はこのサイトでもたびたび話題になっていて、「リンケージ」で検索するとたくさん見付かります。 ********************************* とりあえず、ナレーションをメインのタイムライン、BGM をスクリプトで鳴らすものとします。 BGM として使うサウンドシンボルにはリンケージを設定してください。リンケージ識別子名を、仮に” BGM ”とします。 BGM を鳴らす処理やフェードイン/アウトに必要な設定は、先の方のフレームアクションで予め済ませておきます。 フェードイン / アウトする時は、ムービークリップの enterFrame イベントを使って繰り返しボリュームを変更します。 enterFrame イベントはどのムービークリップのものを借りてもいいのですが、BGM のボリュームをナレーションと別にするためにダミーのムービークリップを作りますから、このムービークリップのものを借りることにします。 ダミーのムービークリップは存在してさえいればいいだけですので、シンボルを作らず、スクリプトで作れる空っぽのムービークリップで充分です。 BGM が不要になった時は、removeMovieClip で削除しても構いません。 ********************************* BGM を鳴らすために必要なスクリプトは、大体、次のようになります。 以下のスクリプトは、全てフレームに設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際はご注意ください) //BGM制御用のダミーのムービークリップを作る this.createEmptyMovieClip( "bgm_clip" , 0 ); //BGMの設定 snd = new Sound( bgm_clip ); snd.attachSound( "BGM" ); snd.setVolume( 100 ); snd.onSoundComplete = function() { //無限ループ再生 snd.start(); }; //BGMを再生 snd.start(); //BGMのボリュームとフェードの速さを管理する変数 bgm_vol = 100; fade_spd = 5; このスクリプトで、BGM が無限ループ再生になります。 停止したい時は snd.stop(); を実行します。 変数 bgm_vol と fade_spd はフェードイン / アウトさせる時に使います。 fade_spd の値を変えると、フェードイン / アウトの速さが変わります。 なお、このスクリプトはサウンドシンボルを書き出したフレームよりも後のフレームに設定してください。 サウンドシンボルを書き出したフレームより前に書くと、シンボルが未定義になって attachSound が失敗し、BGM が鳴らなくなります。 ********************************* フェードインまたはフェードアウトを実行したいフレームには、次のようなスクリプトを書きます。 ●フェードアウトを開始するフレーム //BGMをフェードアウト bgm_clip.onEnterFrame = function() { //ボリュームを徐々に下げる bgm_vol -= fade_spd; //0になったら終了、BGMも止める if( bgm_vol <= 0 ) { bgm_vol = 0; snd.stop(); delete bgm_clip.onEnterFrame; } //ボリュームを設定 snd.setVolume( bgm_vol ); } ●フェードインを開始するフレーム //BGMを鳴らす snd.start(); //BGMをフェードアウト bgm_clip.onEnterFrame = function() { //ボリュームを徐々に上げる bgm_vol += fade_spd; //100になったら終了 if( bgm_vol >= 100 ) { bgm_vol = 100; delete bgm_clip.onEnterFrame; } //ボリュームを設定 snd.setVolume( bgm_vol ); } 早い話が、サウンドのフェードイン / アウトはボリュームを上げ下げする処理を繰り返し実行できる仕組みがあれば何でもいいのです。 ですから、絵のないムービークリップを作ってフレーム間をループし、繰り返し setVolume を実行する方法でも、もちろん構いません。 先述の通り、同じムービークリップにある音はどれも同じボリュームになってしまいますので、ボリュームを個別に操作するなら BGM とナレーションは別のタイムラインの管轄になるようにしなければなりません。 タイムラインに入れた音は、基本的には音を入れたフレームに再生ヘッドが来るたびに再生されます。 ムービークリップのタイムラインで鳴らす時は、連続して同じ音が再生されない(=音を入れたフレームが不要な時に再生されない)ようにする工夫が必要です。 ********************************* スクリプトで鳴らす音は「イベント」と同じです。 上記の例ですと、snd.start(); を実行するごとにサウンドシンボルのインスタンスが作成されて音が鳴り、snd.stop(); でインスタンスが削除されて停止します。 先のスクリプトでは、フェードアウトしてボリュームが 0 になった時に、一旦 snd.stop(); で停止しています。 次に再生する時(今回の例ではフェードインの時)は、snd.start(); を実行しないと音が鳴りません。 ナレーションが再生されている間も BGM を鳴らす時は、フェードアウトの処理内の if の条件を 0 以外の数値に変更し、snd.stop(); を削除してください。 また、この場合はフェードインの時の snd.start(); を削除してください。 フェードアウトの時に snd.stop(); で音を止めなかった場合は、もう1つインスタンスが作られ、BGM が重複して鳴ってしまいます。 スクリプトでは画面と同期させるストリーミング再生のような芸当はできないので、スクリプトで鳴らす方法が必ずしもタイムラインで鳴らすより優れているとは限りません。 逆にスクリプトでしかできないこともありますが、ボリュームの変更くらいならタイムラインを使っても何とかなります。 しかし、BGM のように随時止めたり再生したりボリュームを変えたりということであれば、スクリプトで鳴らす方がタイムラインよりも融通が利いて作りやすいと思います。
補足
さっそくの丁寧なご回答、ありがとうございました。とても心強いです。本当にありがとうございます。 実は、ナレーションもスクリプトで鳴らす予定です。なぜなら、後になってナレーションの差し換えの入る可能性があり、先方でできるだけ修正が楽になるようにということで、ナレーションが終わってから次に進むようにしたいからです。 ですので、ムービークリップはBGM用とNA用と用意しようと思います。 たとえば、ムービークリップの中でifを使ってフェードインとアウトをするようにして、フレームでフラグを立てて操作することはできないかと考えていました。いかがでしょうか?よろしければ、ご回答お願いします。
お礼
本当に細かいところまで、ありがとうございました。 大変、参考になりました。感謝致します。 貴重なお時間を割いていただいて、ありがとうございました。