性格悪い人が優勝

要するに、例えばフッターとヘッダーで、2つのswfファイルをシンクロ再生させたいのです。
同ページ内の2つの別SWFのタイミングを合わせて、連動させようというアイデアな訳ですが、うまいこといきません。


同ファイル内の音声とムービーの同期制御ならぐぐれば判るのですが、ポイントは別swfファイルという点。『片方のloading完了次第、もう一方にstartを投げる』ための記述方法を探しています。


【SWF/A】
if "A" loaded100%, then @@@@."b.swf";start
のようなコマンドをAから投げて、

↓HTML側のjavascriptかなにかで受け取って、

→BにFlashVarsでGET変数受け取りさせる
【SWF/B】<embed src="b.swf" FlashVars="start" ~~>
("@@", "", "GET");
if @@="start" gotoandPlay(3)

、みたいな書き方かなぁ…
などとはまっております。
【同ページ・別SWFの制御、シンクロ再生】のサンプルソースURL求む!ひー


OS/使用ソフト/本体/周辺機器/
WIN2000/FLA8Pro/デスクトップ機/特に無し/

スキル/
言語素養無し・ソースを見て、何が書いてあってどんな動作をするのかは解るReadOnlyの『えせActionScripter』。サンプルソースのつぎはぎをしながらいろいろ覚えてきました。

条件/
SWF/Aは重めの1MB程度のムービーシンボルがrootに置いてあるもの
SWF/Bは軽めの300kb程度のムービーシンボルrootに置いてあるもの


クイズだと思ってお答え頂ければ幸いです。

A 回答 (2件)

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 側のアニメに反映する、といったことも可能です。

相手のメソッドを呼び出す方式ということで情報のやりとりするには少々コツも必要ですが、アイデア次第では面白い使い方もできるかと思います。
機会がありましたら研究してみてください。
    • good
    • 0
この回答へのお礼

う~~~~~~~~~~~~~~~~~ご~~~~~~~~~~~~~~~~~~~~~~~い~~~~~~~~~~~~~~~~~~~~~~~~た~~~~~~~~~~~~~~~~~~~ぁ。

いや、すばらしぃ。ほんとにすばらしい。
ありがとうございました。


なぜこんなに時間がかかっていたのかというと、
別個にローディング処理を入れていました。

■1フレーム目
~スクリプト~
 loading = Math.floor((getBytesLoaded()/getBytesTotal())*100);
 DLbytes = getBytesLoaded();
 Tbytes = getBytesTotal();

~ダイナミックテキスト~
 now loading...
 <$loading$> %
 <$DLbytes$> Bytes
 <$Tbytes$> Total

■2フレーム目
 if (loading == "100") {
 gotoAndPlay(3);
 } else {
 gotoAndPlay(1);
 }

■3フレーム目
<$上記スクリプト$>

■4フレーム目以降
<$元々のムービーシンボル$>

のような形で。

解説頂いたソース中の、
  //完了率を算出
  b_loaded = _root.getBytesLoaded();
  b_total = _root.getBytesTotal();
  b_per = Math.floor( b_loaded / b_total * 100 );
を、ダイナミックテキストに読み込ませようとしたのですが、
・A⇔B通信の仕組み
・1フレームのみでstop;しておく仕組み
が私の知っているローディング処理方法とあわなかったようで、
別途用意した次第です。

説明のわかりやすさにお人柄を感じました。感激です。

お礼日時:2007/01/20 23:40

こちらが参考になるのではないでしょうか


http://hakuhin.hp.infoseek.co.jp/main/js/javascr …

試したわけではないのですが、
・FlashからJavaScriptの関数を実行する
・JavaScriptからFlashにデータを送信する
という項目があるのでこの2つを一連の流れにすることがポイントですかね

数年前に複数のswfを連動させている大規模サイトを見かけたことがあるので、連動自体は実現可能だと思いますよ

この回答への補足

URLリンクありがとうございました。
こちらも一通り読んで試してみました。
確かに外のjsが動いてアラートポップアップが出てきました。

おっしゃったような、
A→JS1 JS2→B
の2つのJSをよしなに繋げるスキルが私にはなく、ニューヨークに辿り着くことはできませんでしたが、知らないテクニックだったので勉強になりました。

今回は、
DPEさんのLocalConnection法を私にとっての正解とさせて頂きましたが、
ぴかいちの素早さで回答を頂いたことに、胸を打たれました。
霊感ヤマカン第六感。次回のFLASH横断ウルトラクイズでお会いできる日を楽しみにしております。

補足日時:2007/01/20 23:42
    • good
    • 0
この回答へのお礼

すばらしい…
now working...
please wait...

お礼日時:2007/01/20 22:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!