itsukichang

フロントエンドが得意なエンジニア.ダーツと旅行とギターが好き

外部swfを読み込んでデータのやり取りする方法

外部swfの変数とか関数を実行したり,値を共有したいとき2つの方法がある.

1つは共有したい変数とかを定義しておくクラス作っておいて,そのクラスのstaticなプロパティ(クラスプロパティ)を参照する方法
もう1つは子swfにpublicな変数,関数作っといてそれにアクセスする方法

方法1:共有したい変数をクラスプロパティとして定義する

  • 共有用
package {	
	public class CommonClass {
		public static var hoge:uint = 10;
	}
}

これを子からも親からもimportしといて,参照(CommonClass.hoge)すれば,一応やりとりできる.
例えば子swfでCommonClass.hoge = 20; ってやった後に,親でtrace(CommonClass.hoge)ってやれば当然20になる.

方法2: 子swfにpublic定義する

  • 子swfの元as
package {
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.events.Event;
	
	public class ChildSwf extends MovieClip {
		private var _hoge:uint = 10;
		public var fuga:uint = 10;
	
		public function ChildSwf() {			
		}
		
		private function hoge():String {
			return "hoge";
		}
		
		public function fuga():String {
			return "fuga";
		}
	}
}

これをパブリッシュして,ChildSwf.swfを生成.

  • 親swfの元as
package {
	import flash.display.Sprite;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.net.URLRequest;
	
	public class Main extends Sprite {
		private var _loader:Loader;
	
		public function Main() {
			_loader = new Loader();
			_loader.load(new URLRequest('ChildSwf.swf'));
			_loader.addEventListener(IOErrorEvent.IO_ERROR, trace);
			_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComp);
		}
		
		private function onComp(e:Event):void {
			trace("load complete");
			//trace((_loader.content as MovieClip)._hoge);  //private定義だから当然取れない
			trace((_loader.content as MovieClip).fuga); //10
			//trace((_loader.content as MovieClip).hoge()); //private
			trace((_loader.content as MovieClip).fuga()); //"fuga"
		}
	}
}

まずLoaderでswfを普通に読み込む.
contentLoaderInfoなイベントを追加して,ハンドラでターゲット(loader)にアクセス.
Loader.contentの型がDisplayObjectなのでMovieClipとして扱って,プロパティや関数にアクセスする.

子から親へ参照してくださいなお願い

これで子の値を親が参照できる訳だけど,例えば子の値が特定のものになったときに初めて親に渡したいときがある.
親からTimerとかEnterframeで監視してもいいけど流石にダサいので何とかならないかと思ったら,普通にDispatchEvent使えた.

なので,子swfを吐き出すasに

public static const CHANGED:String = "changed";
private function hoge():void { //渡したいタイミングで呼び出される関数 例えばマウスクリックとか
     this.dispatchEvent(new Event(CHANGED));
}

って書いといて,親では

(_loader.content as MovieClip).addEventListener("changed", onChange); //_loaderには子swf

private function onChange(e:Event):void {
	trace((_loader.content as MovieClip).fuga);
}

ってやっとけば,必要なタイミングだけ子swfの要素にアクセスすればいいようになる.