質問: 【swf】同ページ・別swfの制御 要するに、例えばフッターとヘッダーで、2つのswfファイルをシンクロ再生させたいのです。 同ページ内の2つの別swfのタイミングを合わせて、連動させようというアイデアな訳ですが、うまいこといきません。 ■ 同ファイル内の音声とムービーの同期制御ならぐぐれば判るのですが、ポイントは別swfファイルという点。『片方のloading完了次第、もう一方にstartを投げる』ための記述方法を探しています。 ■ 【swf/a】 if "a" loaded100%, then @@@@."b.swf";start のようなコマンドをaから投げて、 ↓html側のjavascriptかなにかで受け取って、 →bにflashvarsでget変数受け取りさせる 【swf/b】 ("@@", "", "get"); if @@="start" gotoandplay(3) 、みたいな書き方かなぁ... などとはまっております。 【同ページ・別swfの制御、シンクロ再生】のサンプルソースurl求む!ひー ■ os/使用ソフト/本体/周辺機器/ win2000/fla8pro/デスクトップ機/特に無し/ スキル/ 言語素養無し・ソースを見て、何が書いてあってどんな動作をするのかは解るreadonlyの『えせactionscripter』。サンプルソースのつぎはぎをしながらいろいろ覚えてきました。 条件/ swf/aは重めの1mb程度のムービーシンボルがrootに置いてあるもの swf/bは軽めの300kb程度のムービーシンボルrootに置いてあるもの ■ クイズだと思ってお答え頂ければ幸いです。
回答: flash player 6 以降で使える、localconnection というクラスがあります。 localconnection は swf ファイル同士で通信を行うもので、同じページ内にある違う swf ファイル同士はもちろん、たとえ別の html ファイル上で再生されている swf ファイル同士であっても、両者が html のフレームなどで隔てられていたとしても通信可能です。 localconnection は、送信側と受信側の両方に通信を担当する localconnection オブジェクトを作ります。 このオブジェクトに処理(メソッドといいます)を定義しておいて、相手の持っているメソッドを呼び出すことで通信を行います。 相手を一方的に呼び出すという不器用な通信しかできないのですが、”呼び出されるメソッドの中で相手のメソッドを呼び出す”という形でメソッドを作ると双方向のやりとりになります。 シンクロ再生というといろいろあるかと思いますが、とりあえず、容量の大きい a.swf の読み込み完了に合わせて b.swf を再生させる作例を考えます。 a.swf 側からは b.swf の読み込み完了率を直接把握することはできませんので、localconnection を利用して b.swf から完了率を送信してもらいます。 a.swf では自分の完了率と送られてきた b.swf の完了率を監視し、どちらも 100 %に達したら、自分のタイムラインを進めるとともに b.swf に再生の指令を出します。 先述の通り、localconnection は”相手のメソッドを呼び出す”という形でしか通信できません。 a.swf の都合で b.swf に完了率を送ってもらうならば、 a.swf に、b.swf から完了率を受け取るメソッドを作る。 ↓ b.swf に、a.swf から呼び出されるメソッドを作る。 この中で a.swf に作った先のメソッドを呼び出すようにする。 ↓ a.swf は b.swf にあるメソッドを呼び出す。 という流れになります。 swf ファイルの内容や通信の事情で読み込みに時間がかかり、通信しようとする相手がまだページ内に登場していない可能性も考えられます。 相手がいないと、当然ながら通信は失敗してしまいます。 b.swf が存在しているかどうかは、b.swf と仮に通信してみれば分かります。 何か適当なメソッドを呼び出してみて、応答があれば存在していると判断することができます。 まずはこの確認をしてから先に進む方が無難だと思います。 ************************************** スクリプトの一例です。 a.swf と b.swf の先頭に、それぞれ空白のキーフレームを作ってください。 実際のムービーはフレーム2から作成します。 スクリプトは両方の swf ファイルに書きます。 このスクリプトは、メインのタイムラインに設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください) ● a.swf 側のスクリプト ///////////////////////////////////////////////////// //初期設定 ///////////////////////////////////////////////////// //接続チェックフラグ //正常に接続できた時true、それ以外はfalse connect_flg = false; //b.swfの読み込み完了率を管理する変数 b_per = 0; //行動を決めるステップカウンタ //0:b.swfとの接続確立を待つ 1:自分とb.swfの読み込み完了を待つ act_step = 0; //通信用のオブジェクトの作成と、接続名を定義 a_lc = new localconnection(); a_lc.connect( "a_connector" ); //接続をチェックするメソッド a_lc.connect_test = function( success ) { //通信の結果を保存 connect_flg = success; }; //b.swfから読み込み完了率を受け取るメソッド a_lc.receive_progress = function( loaded_per ) { //b.swfの完了率を保存 b_per = loaded_per; }; ///////////////////////////////////////////////////// //両者の読み込み完了を待つ処理 ///////////////////////////////////////////////////// _root.onenterframe = function() { var a_loaded , a_total , a_per; //ステップカウンタに従って行動 switch( act_step ) { //接続チェック //通信成功を確認して先に進む case 0: a_lc.send( "b_connector" , "connect_check" , "a_connector" ); if( connect_flg ) { act_step++; } break; //自分とb.swfの読み込み完了を待つ case 1: //自分の読み込み完了率を算出する a_loaded = _root.getbytesloaded(); a_total = _root.getbytestotal(); a_per = math.floor( a_loaded / a_total * 100 ); //b.swfの完了率を送信してもらう a_lc.send( "b_connector" , "tell_progress" , "a_connector" ); //自分とb.swfの完了率がともに100%になったら、 //両方を再生してイベント処理を終了する if( a_per >= 100 && b_per >= 100 ) { play(); a_lc.send( "b_connector" , "play_movie" ); delete this.onenterframe; } break; } }; //タイムラインを止めておく stop(); /*****************************************/ ●b.swf側のスクリプト ///////////////////////////////////////////////////// //初期設定 ///////////////////////////////////////////////////// //通信用のオブジェクトの作成と、接続名を定義 b_lc = new localconnection(); b_lc.connect( "b_connector" ); //接続テスト //引数 connector:接続をテストする相手 b_lc.connect_check = function( connector ) { //接続の成功を知らせる this.send( connector , "connect_test" , true ); }; //完了率を送信するメソッド //引数 connector:完了率の送信要求を出してきた相手 b_lc.tell_progress = function( connector ) { var b_loaded , b_total , b_per; //完了率を算出 b_loaded = _root.getbytesloaded(); b_total = _root.getbytestotal(); b_per = math.floor( b_loaded / b_total * 100 ); //完了率を送信する this.send( connector , "receive_progress" , b_per ); }; //タイムラインを動かすメソッド b_lc.play_movie = function() { play(); }; //タイムラインを止めておく stop(); ************************************** localconnection の動作は a.swf と b.swf を同時に再生していないと確認できません。 また、フレーム1でタイムラインを止めているため、「ムービープレビュー」ではただの真っ白な画面になります。 html ページに2つを配置し、できればサーバーにアップしてネット経由で確認してみてください。 なお、サーバー経由で再生した場合、2回目以降はキャッシュから読み込まれ、一瞬で読み込みが終了してほぼ同時に再生が始まることがあります。 再度動作を確認したい時は、キャッシュから a.swf と b.swf を削除してください。 紙面の都合上、全部を詳しく説明できません。 localconnection の文法はヘルプ等をご参考になさってください。 インターネットでも通信相手をただ1人だけ特定する ip アドレスが割り振られているように、通信には情報を送る相手を識別する方法が必要です。 localconnection では、通信の担当者( localconnection オブジェクト)ごとに名前を定義し、この名前をもとに通信を行います。 名前は connect というメソッドで定義します。 上記のスクリプトでは、a.swf 側の通信担当者” a_lc ”の接続名は” a_connector ”、b.swf 側の通信担当者” b_lc ”の接続名は” b_connector ”です。 a_lc と b_lc に、それぞれメソッドを用意しておきます。 a_lc は b_lc のメソッドを、b_lc は a_lc のメソッドを呼び出すことで情報の交換や相手の制御などを行います。 各メソッドの内容はスクリプト中のコメントの通りです。 localconnection の通信は相手のメソッドを呼び出すことでしか実現できませんから、例えば b.swf が存在しているかどうかをチェックするには、 a_lc で、b_lc が持っている connect_check メソッドを呼び出す ↓ connect_check メソッドの中で、a_lc が持っている connect_test を呼び出す といった流れになります。 a_lc の connect_test メソッドは引数(パラメータ)を1つ受け取る設計にしておきます。 すると、b_lc からこのメソッドを呼び出す際にパラメータを渡すことで、 a_lc に b.swf 側の情報を渡せるようになります。 a.swf 側にある connect_test メソッド内では受け取った情報を変数に記録しておくと、メソッドの外でも b.swf から送られてきた情報を利用することができます。 同じ要領で、b.swf の完了率を a.swf に渡します。 a.swf では、自分自身の完了率を算出するとともに b.swf に完了率を問い合わせ、送られてくる b.swf の完了率を監視します。 b.swf にはムービーを再生するメソッド(上記のスクリプトでは” play_movie ”メソッド)を予め用意しておきます。 a.swf と b.swf の読み込み完了率が両方とも 100 %に達したら、自分のタイムラインを動かすと同時に b_lc の play_movie メソッドを呼び出して、b.swf に再生指令を送ります。 指令を送って再生するというよりも、a.swf から b.swf を動かしている感覚に近いかもしれません。 今回は a.swf 側で b.swf の完了率を受信し、両方とも読み込みが完了したら再生する作例を考えましたが。 他にも、例えば a.swf 側のデータを送って b.swf 側のアニメに反映する、といったことも可能です。 相手のメソッドを呼び出す方式ということで情報のやりとりするには少々コツも必要ですが、アイデア次第では面白い使い方もできるかと思います。 機会がありましたら研究してみてください。