トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   ActionScript 3.0 特設会議室
     外部読込みされるMC内で、読込元の変数を参照したい
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
kirarin
Åê¹ÆNo.39360
投稿日時: 2008-6-29 15:57
職人
居住地: 彩の国
投稿: 214
使用環境:
Windows7
IE 8
Flash CS4
Flash Player WIN 10,0,45,2
-------------------------
WindowsXP Professional SP3
IE7.0
Flash 8 Professional
Flash Player 10.0.12.36
-------------------------
Windows2003 Sp1
IE6.0 SP1
Flash MX 2004 ...
外部読込みされるMC内で、読込元の変数を参照したい
kirarinです。
いつもお世話になっております。
表題の件で質問いたします。

main.swf内で、sub.swfをロードするプログラムを作成しています。(sub.swfは、独立した別ファイル)
この読込まれるsub.swf内で、読込元であるmain.swfの中で定義されているa_arrayという配列を参照したいのですが、
「条件は未定義であり、プロパティがありません。」
というエラーになります。

a_arrayはmain.swf内で定義されているものなので、考えてみれば当然かもしれません。
このエラーを無視してsub.swfをパブリッシュし、main.swfからsub.swfをロードして動作させても、やはりsub.swf内からa_arrayは参照できず上記と同じエラーメッセージが表示されてしまいました。

sub.swfの中で、a_arrayを扱う(例えばlengthを取得する)には、どのように作成したらよいでしょうか。

[追記]
開発と運用で、rootのさすものが異なることが問題かな、と考えております。


----------------
Kirarin

ニノミヤ カズノリ
Åê¹ÆNo.39366
投稿日時: 2008-6-29 23:25
職人
居住地: 東京
投稿: 430
使用環境:
CS4
.4.11, .5.7
XP Pro(sp3)
Flash Player 10,0,22,87,
AIR 1.5.1,
IE 5.5 & 6 & 7 & 8,
Firefox 2.0.0.20 & 3.0.11 & 3.5,
Opera 9.64,
Safari 4,
Google Chrome 2.0.172.31,
Netscape 7.1
Re: 外部読込みされるMC内で、読込元の変数を参照したい
読み込む側、読み込まれる側がどちらも AS3.0 である事を前提で説明します。
読み込まれる側(sub.swf)が親を辿って行けば、読み込む側(main.swf)にアクセスする事が可能です。

main.swf:1フレーム目
var a_array:Array = [1, 2, 3, 4];

var loader:Loader = new Loader();
loader.load(new URLRequest("sub.swf"));
addChild(loader);

sub.swf:1フレーム目
stage.addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(event:MouseEvent):void
{
	if (this.parent.parent.hasOwnProperty("a_array"))
	{
		trace(MovieClip(this.parent.parent).a_array);
	}
}
永井勝則
Åê¹ÆNo.39367
投稿日時: 2008-6-30 0:30
職人
居住地: 白馬村
投稿: 796
使用環境:
Windows 7 :Flash CS4:
10.6.8 :Flash CS5.5
Re: 外部読込みされるMC内で、読込元の変数を参照したい
ほぼ実験のように3つの方法を考えました。
1)表示オブジェクトの階層をたどる方法
2)LocalConnectionを使う方法
3)共有オブジェクトを使う方法

1)
//Main.swfのメインのタイムライン
var a_array:Array=["メインの配列1","メインの配列2"];

var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onCompleteListener);

loader.load(new URLRequest("Sub.swf"));

function onCompleteListener(evt:Event):void {
	//trace(loader.content)
	addChild(loader);
	
}

//Sub.swfのメインのタイムライン
// btn:MovieClip、info_txt:TextFieldがある
addEventListener(Event.ADDED_TO_STAGE,onAddedListener);

function onAddedListener(evt:Event):void {
	info_txt.text="追加された";
	btn.addEventListener(MouseEvent.CLICK,onClickListener);
}

function onClickListener(evt:MouseEvent):void {
	var maintimeline:DisplayObject=stage.getChildAt(0);
	info_txt.text="クリック"+"\n"+MovieClip(maintimeline).a_array;
}


2)
//Main.swfのメインのタイムライン
var a_array:Array=["値1","値2"];

var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onCompleteListener);

loader.load(new URLRequest("Sub.swf"));

var lc:LocalConnection=new LocalConnection();

function onCompleteListener(evt:Event):void {
	addChild(loader);
	lc.send("lcconn","sendMes",a_array);
}

//Sub.swfのメインのタイムライン
var lc:LocalConnection=new LocalConnection()
var client:CustomClient=new CustomClient()

lc.client = client
lc.connect("lcconn");

addEventListener(Event.ADDED_TO_STAGE,onAddedListener);

function onAddedListener(evt:Event):void {
	info_txt.text="追加された";
	btn.addEventListener(MouseEvent.CLICK,onClickListener);
}

function onClickListener(evt:MouseEvent):void {
	info_txt.text="クリック"+"\n"+client.getArray()
}

// CustomClientクラス
package {
	public class CustomClient extends Object {
		private var myArray:Array;
		// これはよくない! 悪用される!
		public function sendMes(arr:Array):void {
			myArray=arr;
		}
		public function getArray():Array {
			return myArray;
		}
	}
}


3)
//Main.swfのメインのタイムライン
var a_array:Array=["値1","値2"];

var so:SharedObject = SharedObject.getLocal("test","/");
so.data.arr = a_array;
so.flush();

var loader:Loader=new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onCompleteListener);
loader.load(new URLRequest("Sub.swf"));

function onCompleteListener(evt:Event):void {
	addChild(loader);
}

//Sub.swfのメインのタイムライン
addEventListener(Event.ADDED_TO_STAGE,onAddedListener);

function onAddedListener(evt:Event):void {
	info_txt.text="追加された";
	btn.addEventListener(MouseEvent.CLICK,onClickListener);
}

function onClickListener(evt:MouseEvent):void {
	var so:SharedObject = SharedObject.getLocal("test","/");
	if (so.size == 0) {
		// 共有オブジェクトは存在しない
	} else {
		info_txt.text="クリック"+"\n"+so.data.arr;
	}
}


----------------
永井勝則:
himco.jp :

野中文雄
Åê¹ÆNo.39369
投稿日時: 2008-6-30 1:40
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 外部読込みされるMC内で、読込元の変数を参照したい
簡単に済ませるなら、配列アクセス演算子を使う方法があります。sub.swf書出し時のランタイムエラーは、気にしなくて構いません。
trace(parent.parent["a_array"], stage.getChildAt(0)["a_array"]);

確実なのは、読込み側(main.swf)から読込まれる側(sub.swf)に、変数なりタイムラインの参照を渡すことでしょうか。
// ファイル: main.swf
// フレームアクション
var myLoader:Loader = new Loader();
addChild(myLoader);
var myRequest:URLRequest = new URLRequest("sub.swf");
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
myLoader.load(myRequest);
function onComplete(eventObject:Event):void {
	MovieClip(myLoader.content).xSetReference(a_array);
}

// ファイル: sub.swf
// フレームアクション
var a_array:Array;
function xSetReference(_array:Array):void {
	a_array = _array;
	trace(a_array);
}

引用:
kirarinさんは書きました:
main.swf内で、sub.swfをロードするプログラムを作成しています。(sub.swfは、独立した別ファイル)
この読込まれるsub.swf内で、読込元であるmain.swfの中で定義されているa_arrayという配列を参照したいのですが、
「条件は未定義であり、プロパティがありません。」
というエラーになります。


----------------
 

kirarin
Åê¹ÆNo.39370
投稿日時: 2008-6-30 9:56
職人
居住地: 彩の国
投稿: 214
使用環境:
Windows7
IE 8
Flash CS4
Flash Player WIN 10,0,45,2
-------------------------
WindowsXP Professional SP3
IE7.0
Flash 8 Professional
Flash Player 10.0.12.36
-------------------------
Windows2003 Sp1
IE6.0 SP1
Flash MX 2004 ...
Re: 外部読込みされるMC内で、読込元の変数を参照したい
>ニノミヤ カズノリ様(先ほど間違えていました、大変失礼いたしましたm(__;)m)

kirarinです。
ご回答ありがとうございました。

いただいたスクリプトを試してみました。
クリックせずに、ロードされた直後に取得したかったので、sub.swfのスクリプトの最後に↓を追加してみました。
stage.dispatchEvent(new MouseEvent(MouseEvent.CLICK));

無事、a_arrayの内容を取得することができました。
main.swfを開発環境で開きながら、sub.swfを作成する、という手順で試しました。(sub.swfだけではa_arrayが取得できないので)

sub.swfでこのa_arrayをいろいろと使用するとしたら、sub.swf内で定義した別の配列にセットして使ったほうがよさそうですね!
ありがとうございました。m(__)m


----------------
Kirarin

kirarin
Åê¹ÆNo.39371
投稿日時: 2008-6-30 11:05
職人
居住地: 彩の国
投稿: 214
使用環境:
Windows7
IE 8
Flash CS4
Flash Player WIN 10,0,45,2
-------------------------
WindowsXP Professional SP3
IE7.0
Flash 8 Professional
Flash Player 10.0.12.36
-------------------------
Windows2003 Sp1
IE6.0 SP1
Flash MX 2004 ...
Re: 外部読込みされるMC内で、読込元の変数を参照したい
>永井様

kirainです。
3通りもの例をあげていただき、大変参考になりました。ありがとうございました。

(1)
自分には一番分かりやすかったです。
ADDED_TO_STAGEというイベントをあることも知り、勉強になりました。
自分でも試してみて、実際に受け取ることができました。
var maintimeline:DisplayObject=stage.getChildAt(0);
で、親の参照を受け取っているのだと思いますが、例えば、sub.swf以外にも外部読み込みしていたり、addChildしているオブジェクトがあった場合、getChildAtのインデックス番号は変わる、ということになりますでしょうか。

(2)
これまで自分では使ったことがない方法でした。
クリックではなく、ロード直後にすぐa_arrayを参照しようと、onAddedListenerの中をコメントにして、
info_txt.text="クリック"+"\n"+client.getArray()
だけを記述してみましたが、LocalConnectionの接続がまだ完了していない?のか、取得できませんでした。
(LocalConnectionがactivate になるのを待って取得する?)

(3)
こちらもこれまで使ったことがありませんでした。
Sub.swfのonAddedListenerの中身をonClickListenerと同じ記述にしても取得することができました。
が、a_arrayのサイズが大きい場合なども考慮した場合は、読込みの完了などを取得して実行した方がよい、ということでしょうか。


(2)(3)の2種類については、実際に使ったことがありませんので、考え違いなどありましたら、申し訳ございません。


----------------
Kirarin

kirarin
Åê¹ÆNo.39372
投稿日時: 2008-6-30 11:50
職人
居住地: 彩の国
投稿: 214
使用環境:
Windows7
IE 8
Flash CS4
Flash Player WIN 10,0,45,2
-------------------------
WindowsXP Professional SP3
IE7.0
Flash 8 Professional
Flash Player 10.0.12.36
-------------------------
Windows2003 Sp1
IE6.0 SP1
Flash MX 2004 ...
Re: 外部読込みされるMC内で、読込元の変数を参照したい
>野中様

kirarinです。
ご回答ありがとうございました。

配列アクセス演算子を使用して試してみました。
sub.swfの1フレーム目に頂いたtrace文を記述したのですが、「null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。」のエラーとなってしまいました。
しかし、sub.swfの2フレーム目以降に書いて試したところ、どちらの記述でも取得することができました。
このテストでは1フレームだけ待てば可能でしたが、やはりsub.swf読み込み完了を待つ処理が、sub.swfの冒頭に必要と考えた方がよろしいでしょうか。
(sub.swfのサイズによっては待ち時間が変わる?)


参照を渡す方法も試してみました。
ロードが完了した後であれば、sub.swf内の関数もmain.swfの方から動作させることができるのですね。
こちらでも、sub.swfの1フレーム目にa_array.lengthをtraceしてみると参照できませんでしたが、2フレーム目以降であれば可能でした。
分かりやすい所で、sub.swfを1フレーム目で止めておいて、xSetReference内にthis.play()を追加、などとした方がよさそうかな、と考えております。
(蛇足で恐縮ですが、main.swf内のonComplete内に、MovieClip(myLoader.content).play()を追加するのと同じだと思いますが、どちらを採用するか考え方について何かありましたら、アドバイスいただけますと幸いです)


上記、簡単な方法で対応できるのはとてもラッキー!と思いましが、プログラムとして、subがmainの変数を参照していることを明確化しておいた方が、後々のためにはよいのかな、と思いました。


----------------
Kirarin

野中文雄
Åê¹ÆNo.39373
投稿日時: 2008-6-30 12:39
ちょんまげら
居住地: 東京
投稿: 4531
使用環境:
CS5.5 .6.8 Vista Home Premium (SP1)
Re: 外部読込みされるMC内で、読込元の変数を参照したい
Loader.load()メソッドを呼出す前に、Loaderインスタンスを表示リストに加えていますか(DisplayObjectContainer.addChild()メソッドの呼出し)?読込まれたsub.swfの第1フレームアクションが処理されるときには、読込み側main.swfのタイムラインや変数は、アクセス可能な状態になっていると思います。

関数xSetReference()は、Loaderインスタンスにsub.swfが読込まれるのを待っていますので、sub.swfの第1フレームアクションの処理時にはまだ呼出されていないでしょう。参照する変数を使って最初に行いたい処理がある場合には、trace()関数のステートメントと同じようにxSetReference()関数内に記述するか、そこから別の関数を呼出すかするのがよいと思われます。

どうしても、xSetReference()とは別途に処理したい場合には、変数に値が設定されるのを待つ方法になるでしょうか。
addEventListener(Event.ENTER_FRAME, onInitialized);
function onInitialized(eventObject:Event):void {
	if (a_array) {
		trace(a_array);
		removeEventListener(Event.ENTER_FRAME, onInitialized);
	}
}

引用:
kirarinさんは書きました:
配列アクセス演算子を使用して試してみました。
sub.swfの1フレーム目に頂いたtrace文を記述したのですが、「null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。」のエラーとなってしまいました。
...[中略]...
参照を渡す方法も試してみました。
ロードが完了した後であれば、sub.swf内の関数もmain.swfの方から動作させることができるのですね。
こちらでも、sub.swfの1フレーム目にa_array.lengthをtraceしてみると参照できませんでしたが、2フレーム目以降であれば可能でした。


----------------
 

kirarin
Åê¹ÆNo.39374
投稿日時: 2008-6-30 13:49
職人
居住地: 彩の国
投稿: 214
使用環境:
Windows7
IE 8
Flash CS4
Flash Player WIN 10,0,45,2
-------------------------
WindowsXP Professional SP3
IE7.0
Flash 8 Professional
Flash Player 10.0.12.36
-------------------------
Windows2003 Sp1
IE6.0 SP1
Flash MX 2004 ...
Re: 外部読込みされるMC内で、読込元の変数を参照したい
>野中様

kirarinです。
再度ありがとうございます。

おっしゃる通り、addChildはあとになっていました。
野中さんが最初に投稿してくださった方の内容にありましたloadの方法で再度試したところ、sub.swfの1フレーム目でも、配列アクセス演算子を使って取得することができました。失礼いたしました。

loaderのEvent.COMPLETEイベント内でaddChildする方が、これまでにもあった「処理の完了を待って実行」のような感じがしてよいかと思っていましたが、このような場合があるのですね。
読込後すぐに表示してもよい場合は、先にaddChildするようにしようと思います。

今回ご教示いただいたスクリプトを、sub.swfの1フレーム目に記述して試してみました。
このスクリプトを追加したほうが、確かに確実なような気がしました。
また、このような場合、a_arrayがtrueであれば「変数に値が設定された」と判断できるのも勉強になりました。

ご補足ありがとうございました。



----------------
Kirarin

永井勝則
Åê¹ÆNo.39378
投稿日時: 2008-6-30 22:15
職人
居住地: 白馬村
投稿: 796
使用環境:
Windows 7 :Flash CS4:
10.6.8 :Flash CS5.5
Re: 外部読込みされるMC内で、読込元の変数を参照したい
var maintimeline:DisplayObject=stage.getChildAt(0);
のmaintimelineはStageオブジェクトの1つめの子で、つまりメインのタイムラインです。
Sub.swfはmaintimelineの子です。

たとえば、複数のSWFファイルをロードして追加するたびに、
trace(DisplayObjectContainer(maintimeline).numChildren);
で子の数を出力すると、子の数が増えていきます。

またメインのタイムラインでmc1というname変数を持つMovieClipオブジェクトを表示リストに追加しておくと、
trace(DisplayObjectContainer(maintimeline).getChildByName("mc1").name)
というコードで、mc1のnameを出力することができます。
mc1もメインのタイムラインの子です。
つまりSub.swfとmc1は兄弟の関係にあります。

Flash PlayerがSWFを格納する空間には、
まずStageがあり、その下にメインのタイムライン(メインクラス)があり、その下にこのSub.swfやmc1があります。




----------------
永井勝則:
himco.jp :

(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops