HAKUHIN's home page
更新履歴
 
 

 

ディスプレイオブジェクトコンテナとは?
 

■ DisplayObjectContainer とは?

スプライトやムービークリップなどのインスタンスは、インスタンスの中に別のインスタンスを入れ子として複数格納する事ができます。
 
 
 

親インスタンスは、子インスタンスを『表示リスト』の中に格納して、管理することができます。

DisplayObjectContainer クラスを使用すると『表示リスト』にアクセスする事ができます。
 
 
■表示リスト

『表示リスト』を使用すると インスタンスを、Flash 画面上に表示する事ができます。

また手前や奥といった奥行きの優先度を入れ替えたりもできます。

さらにグローバル座標とローカル座標間の座標変換や当たり判定などのメソッドもあります。
 
■ 親インスタンスになれるのは?

親インスタンスになれるのは、DisplayObjectContainer から派生しているクラスです。 ムービークリップやスプライトなどがあります。
 
■ 子インスタンスになれるのは?

子インスタンスになれるのは、DisplayObject から派生しているクラスです。 ムービークリップやスプライト、シェイプテキストフィールドビットマップ、ビデオなどがあります。
 
■ DisplayObjectContainer クラスの派生について

ディスプレイオブジェクトコンテナは以下のクラスから派生しています。ここで解説してない分はリンク先に解説がありますので合わせてご覧下さい。
 
Object
↓派生
EventDispatcher
↓派生
DisplayObject
↓派生
InteractiveObject
↓派生
DisplayObjectContainer
 
関連のあるクラス(主なクラスを抜粋)
Stage , MovieClip , Sprite , Loader , MainTimeline
 
 

■stage を基とした階層について

Flash の画面上で最も上の階層(ルート)となるのが stage です。
 
stage の『表示リスト』に、インスタンスを登録するとそのインスタンスはFlash 画面上に表示されるようになります。
 
stage の『表示リスト』に登録済みであるインスタンスがあるとします。そのインスタンスの『表示リスト』にさらに別のインスタンスを登録することができます。
 
続けて表示リストにどんどん登録していくと、下の画像のような stage を基とした木構造が出来上がります。
 
 
■インスタンスを Flash 画面上に表示するには?

あるインスタンスが stage から発生する表示リストの子としてどこかに登録されていれば、そのインスタンスは Flash 画面上に表示されます
 
逆に、別のインスタンスの表示リストに登録されていたとしても、最終的に stage までの連結が途切れていれば、そのインスタンスは Flash 画面上に表示されません
 
■表示リスト登録による表示の変化について

子のインスタンスは親のインスタンスの座標や角度、スケール、カラー、ブレンド、フィルタなどを継承した状態で表示されます。
 
親の姿勢に変化があれば子も同じように姿勢が変化します。親の色に変化があれば子も同じように色が変化します。
 
また、表示リストに登録したときの番号が奥行きとして反映されます。番号が大きいほど表示リスト内で手前に表示されます
 
■stage の表示リストに登録した場合の注意点

stage は DisplayObject クラスから派生していますが、少し特殊で座標や回転といった姿勢に関するプロパティが読み出し専用となり変更することができません

stage の表示リストに直接インスタンスを登録することもできますが、Flash 画面全体を移動したり拡大したりといった事をしたい場合は、次に解説するroot1 の下にぶら下げて登録していくのがいいでしょう。
 
■静的に配置したオブジェクト

あらかじめタイムラインのルート上に静的に配置したオブジェクトは、stage の表示リストに登録されそうな気がしますが 実際は別のところに登録されています。
 
stage の『表示リスト』の 0 番目"root1" というインスタンス名を持つオブジェクトがあります。 クラス名は "MainTimeline" です。このオブジェクトの『表示リスト』に登録されています。
 
 
■表示リストに登録されたオブジェクトにアクセスする
 
■Stage にアクセス

stage と記述すると Stage オブジェクトにアクセスできます。
 
■ルートにアクセス

root と記述すると 表示リストのルートとなるオブジェクトにアクセスできます。親を1段階ずつ調べていき、
 
Loader が見つかった場合は、Loader オブジェクト
MainTimeline が見つかった場合は、MainTimeline オブジェクト
Stage が見つかった場合は、Stage オブジェクト
 
が得られます。取得できるのは DisplayObject 型となります。
 
■1つ上にアクセス

parent と記述すると 1 つ上の階層のオブジェクトにアクセスできます。
 
取得できるのは DisplayObject 型となります。
 
■自身にアクセス

this と記述すると自身のオブジェクトにアクセスできます。
 
一番上の階層で this と記述した場合 "MainTimeline" オブジェクトにアクセスできます。
 
■ドットシンタックスを使ってアクセスする

ドットシンタックスは、静的に配置したオブジェクト限定で動作します。

あらかじめオブジェクトに「インスタンス名」を付けておきます。Flash を書き出すと「親のインスタンス」のプロパティに「子のインスタンス名」が追加されます。 そのプロパティには、「子のインスタンスの参照」が格納されます。
 
this から開始して、インスタンス名をドットで連結していけば、階層を辿って相対パスで「子のインスタンス」にアクセスできます。 parent と記述すると1つ上の階層へ登ることができます。
 
MainTimeline からもドットシンタックスを使用できますが、stage からドットシンタックスを使用することはできません。
 
rootparent を使用すると DisplayObject 型として扱われるので、その後にドットシンタックスを記述すると書き出し時に「未定義である可能性が高い○○○に静的型 flash.display:DisplayObjectContainer の参照を使用してアクセスしています。」というエラーとなります。
 
いったん Object 型に変換したりして回避する必要があります。
 
たとえば、
 
「一番上のタイムライン」に配置したムービークリップに "aaa" というインスタンス名を付けて、その中に配置したムービークリップに "bbb" というインスタンス名をつけて、その中に配置した2つのムービークリップにそれぞれ "ccc"、"ddd" というインスタンス名を付けたとします。
 
 
 
「一番上のタイムライン」から 「"ccc" のインスタンス」にアクセスしたい場合は、以下のように記述できます。
 
静的に配置したインスタンス ccc にアクセスする

trace(Object(root).aaa.bbb.ccc);
trace(this.aaa.bbb.ccc);

trace(Object(root).aaa.bbb.ccc.name);
trace(this.aaa.bbb.ccc.name);
 
「インスタンス "ccc"」 のタイムラインから 「インスタンス "aaa"」 にアクセスしたい場合は、以下のように記述できます。
 
静的に配置したインスタンス ccc から aaa にアクセスする

trace(this.parent.parent);
trace(this.parent.parent.name);
 
「インスタンス "ddd"」 のタイムラインから 「インスタンス "ccc"」 にアクセスしたい場合は、以下のように記述できます。
 
静的に配置したインスタンス ddd から ccc にアクセスする

trace(Object(this.parent).ccc);
trace(this.parent["ccc"].name);
 



 

インスタンスを表示リストに登録する
 


■インスタンスを作成する

まずは、テキストフィールドを作ってみましょう。
 
new 命令を使ってクラスをインスタンス化します。
 
テキストフィールドインスタンスを作成する

var text_field:TextField = new TextField();
text_field.text = "表示テスト";
 
■ stage の表示リストにインスタンスを登録する
 
サンプルをダウンロード
 
インスタンスを作成しただけでは Flash の画面に表示されません。
 
表示されるためにはインスタンスを表示リストに登録する必要があります。
 
表示リストに登録するには、addChild()メソッドを使用します。
 
addChild()メソッドを使用すると、最善面にインスタンスを登録することができます。引数に DisplayObject オブジェクトを指定します。
 
ステージに配置したいのであれば stage の表示リストに登録します。
 
インスタンス.addChild ( インスタンス );
第01引数 ディスプレイオブジェクトのインスタンス
戻り値 登録したディスプレイオブジェクト
 
stage の表示リストに登録する

var text_field = new TextField();
text_field.text = "表示テスト";

stage.addChild(text_field);
 
表示リストには、複数のインスタンスを登録することができます。
 
だたし、任意のインスタンスを同じ表示リストに複数回登録したり、複数の表示リストに同じインスタンスを登録したり、表示リストに自分自身を登録する事はできません。
 
■任意のインスタンスに子インスタンスを登録する
 
サンプルをダウンロード
 
では別のインスタンスの表示リストにも登録してみましょう。
 
スプライトを作成して stage に配置し、さらにテキストフィールドを作成してスプライトに配置してみましょう。別のインスタンスの表示リストに登録すれば親子関係を持たせる事ができます。
 
スプライトを作成して stage に配置し、テキストフィールドを作ってスプライトに配置する

var sprite = new Sprite();
stage.addChild(sprite);
sprite.y = 100;

var text_field = new TextField();
text_field.text = "表示テスト";
sprite.addChild(text_field);
 
■インスタンスが持つ子の数を調べる

インスタンスがどれだけ子をもっているか調べるには numChildren プロパティを使用します。このプロパティは自分自身の表示リストに登録された子の数を調べます。
 
stage が持つ子のインスタンス数を調べる

var num = stage.numChildren;
 
 


■順番について

addChildAt() メソッドを使うと番号で奥行き優先順位を指定して登録する事ができます。
 
番号は 0 から始まる数値で、高いほど手前である事を表しています。
 
 
注意点としては、この順番は固定された数値ではありません。 2 番目に登録したからといって常に 2 番目に存在し続けるとは限りません。

表示リストが変更されるたびに 0 から順番に割り振られ直すため、番号で奥行きを管理するのは難しくなります。番号ではなく、任意のインスタンスを基準として、ここから手前、奥に配置するという感じで管理するのがいいでしょう。
 
■順番を指定して配置する
 
サンプルをダウンロード
 
addChildAt() メソッドの、第 01 引数に登録したいインスタンス、第 02 引数に順番を指定します。
 
順番は 0 から『登録されてる個数』までの数値が指定できます。いきなり1000番目に登録したりするとエラーとなります。
 
インスタンス.addChildAt ( インスタンス , 番号 );
第01引数 ディスプレイオブジェクトのインスタンス
第02引数 登録したい表示リストの番号 (『 0 ~ 登録されてる個数』以外を指定するとエラー)
戻り値 登録したディスプレイオブジェクト
 
stage の表示リストの 0 番目にテキストフィールドを登録する

var text_field = new TextField();
text_field.text = "表示テスト";

stage.addChildAt(text_field ,0);
 
指定した番号にすでにインスタンスが登録されている場合は、まずその番号に新しいインスタンスが登録され、もともとあったインスタンスを含む手前のインスタンスは上(手前)に移動し、挟み込むような感じになります。
 
 
 
stage の表示リストの最前面にくる番号を調べてテキストフィールドを登録する

var text_field = new TextField();
text_field.text = "表示テスト";

var depth = stage.numChildren;
stage.addChildAt(text_field ,depth);
 
■自分がどの順番に登録されているか調べる

自分がどの番号に登録されているか調べるには、getChildIndex()メソッドを使用します。親のインスタンスからメソッドを呼び出し、引数に調べたい子のインスタンスを指定します。
 
ただし、存在していないインスタンスを調べようとするとエラーとなるので注意が必要です。
 
インスタンス.getChildIndex ( インスタンス );
第01引数 ディスプレイオブジェクトのインスタンス
戻り値 現在登録されている番号
 
テキストフィールドがどの番号に配置されているか調べる

var text_field = new TextField();
text_field.text = "表示テスト";

stage.addChildAt(text_field ,0);
var depth = stage.getChildIndex(text_field);
 
■任意の登録済みインスタンスを基準にして手前か奥に配置する

『表示リストに登録済みのインスタンス』を基準にして、そこから手前か奥かに配置したい場合は、まずインスタンスが登録されている番号を調べます。
 
奥であれば数値をそのまま指定して登録します。
 
手前であれば +1 した値を指定して登録します。
 
インスタンス b と c の間にテキストフィールドを配置する

var a = new Sprite();
var b = new Sprite();
var c = new Sprite();

stage.addChild(a);
stage.addChild(b);
stage.addChild(c);

var text_field = new TextField();
text_field.text = "表示テスト";

var depth = stage.getChildIndex(b);
stage.addChildAt(text_field ,depth + 1);
 
 

 

インスタンスを表示リストから外す
 


■インスタンスを表示リストから外す
 
サンプルをダウンロード
 
表示リストから登録を外すには removeChild()メソッドを使用します。
 
このメソッドは、親のインスタンスの表示リストから子のインスタンスの登録を外します。外すだけなのでどこかで参照されていれば破棄される事はありません。
 
親のインスタンスからremoveChild()を呼び出し、の第01引数に外したい子のインスタンスを指定します。
 
インスタンス.removeChild ( インスタンス );
第01引数 ディスプレイオブジェクトのインスタンス
戻り値 削除されたインスタンス
 
stage に配置したテキストフィールドを外す

var text_field = new TextField();
text_field.text = "表示テスト";

stage.addChild(text_field);
stage.removeChild(text_field);
 
■順番を指定してインスタンスを表示リストから外す
 
サンプルをダウンロード
 
順番指定で表示リストから登録を外すには removeChildAt()メソッドを使用します。
 
親のインスタンスからremoveChildAt()を呼び出し、の第01引数に外したい子の番号を指定します。
 
インスタンス.removeChildAt ( 番号 );
第01引数 番号
戻り値 削除されたインスタンス
 
stage の表示リストの 0 番目に配置したインスタンスを外す

var text_field = new TextField();
text_field.text = "表示テスト";

stage.addChildAt(text_field ,0);
stage.removeChildAt(0);
 
 

 

インスタンス同士の重ね順序を入れ替える
 


■インスタンス同士の重ね順序を入れ替える
 
サンプルをダウンロード
 
表示リストの順番を入れ替えるには、swapChildren()メソッドを使用します。
 
親のインスタンスからswapChildren()を呼び出し、の第01引数と第02引数に入れ替えたい子のインスタンスを指定します。
 
インスタンス.swapChildren ( "インスタンス名" , "インスタンス名" );
第01引数 片方のインスタンス名
第02引数 もう片方のインスタンス名
戻り値 なし
 
stage に配置したインスタンス a と b の順序を入れ替える

var a = new Sprite();
var b = new Sprite();

stage.addChild(a);
stage.addChild(b);

stage.swapChildren(a , b);

trace(stage.getChildIndex(a));
trace(stage.getChildIndex(b));
 
■順番を指定してインスタンス同士の重ね順序を入れ替える
 
サンプルをダウンロード
 
順番を指定して表示リストの順番を入れ替えるには、 swapChildrenAt()メソッドを使用します。
 
親のインスタンスからswapChildrenAt()を呼び出し、の第01引数と第02引数に入れ替えたい番号を指定します。
 
インスタンス.swapChildrenAt ( 番号 , 番号 );
第01引数 片方の番号
第02引数 もう片方の番号
戻り値 なし
 
stage に配置したインスタンス 0 番目と 1 番目の順序を入れ替える

var a = new Sprite();
var b = new Sprite();

stage.addChildAt(a , 0);
stage.addChildAt(b , 1);

stage.swapChildrenAt(0 , 1);

trace(stage.getChildIndex(a));
trace(stage.getChildIndex(b));
 
 

 

インスタンスが表示リストに存在するか調べる
 


■インスタンス名を指定して表示リストに存在するか調べる

インスタンス名を使って、表示リストに登録されているか調べるには、getChildByName()メソッドを使用します。
 
親のインスタンスからgetChildByName()を呼び出し、の第01引数にインスタンス名を指定します。
 
もしインスタンスが見つかれば、インスタンスのオブジェクトを返します。見つからなければ null が返ります。
 
インスタンス.getChildByName ( "インスタンス名" );
第01引数 インスタンス名
戻り値 インスタンスが見つかれば、ディスプレイオブジェクトのインスタンス 見つからなければ null を返す
 
stage にムービークリップ "instance" が配置されているか調べる

var mc = new MovieClip();
mc.name = "instance";

stage.addChild(mc);

var instance = stage.getChildByName("instance");
 
■順番を指定して表示リストに存在するか調べる

番号を使って、表示リストに登録されているか調べるには、getChildAt()メソッドを使用します。
 
親のインスタンスからgetChildAt()を呼び出し、の第01引数に番号を指定します。
 
もしインスタンスが見つかれば、インスタンスのオブジェクトを返します。見つからなければ null が返ります。
 
インスタンス.getChildAt ( 番号 );
第01引数 番号
戻り値 インスタンスが見つかれば、ディスプレイオブジェクトのインスタンス 見つからなければ null を返す
 
stage の 0 番目にインスタンスが配置されているか調べる

var mc = new MovieClip();
stage.addChildAt(mc ,0);

var instance = stage.getChildAt( 0 );
 
■表示リストに登録されているインスタンスをすべて調べる

numChildren プロパティを使うと、表示リストに保持しているインスタンスの総数を調べることができます。
 
そして getChildAt() メソッドを使って 0 から総数分のインスタンスを順番に調べていきます。
 
stage の表示リストに登録されているインスタンスをすべて列挙する

var a = new MovieClip();
var b = new MovieClip();
var c = new MovieClip();
stage.addChild(a);
stage.addChild(b);
stage.addChild(c);

var num = stage.numChildren;
var i;
for(i=0;i < num;i++){
	var mc = stage.getChildAt(i);
	trace(mc);
}
 
 

 

ローカル座標からグローバル座標へ変換する
 


■ローカル座標からグローバル座標へ変換する

どこかにに配置したインスタンスの座標系をローカル座標と呼ぶことにします。Flashのスクリーン上の座標をグローバル座標と呼ぶことにします。
 
 
ローカル座標が、グローバル座標ではどこに当たるかを調べるには localToGlobal() メソッドを使用します。子のインスタンスから呼び出します。
 
インスタンス.localToGlobal ( Point型 );
第01引数 座標をPoint型にして指定
戻り値 変換された座標がPoint型で返ります
 
スプライトのローカル座標 (10,20) がスクリーン座標上でどこに来るか調べる

var sprite= new Sprite();

// 適当に姿勢を変更
sprite.x = 40;
sprite.y = 90;
sprite.rotation = -30;

stage.addChild(sprite);

var l_pos : Point = new Point(10,20);
var g_pos : Point = sprite.localToGlobal(l_pos);

trace("x : " + g_pos.x + " y : " + g_pos.y);
 
■ローカルベクトルからグローバルベクトルへ変換する

おまけですが、行列情報を使って求めることもできます。座標ではなくベクトルを変換したい場合は、こちらを使います。
 
行列を使って、座標とベクトルをローカルからグローバルへ変換する

var sprite= new Sprite();

// 適当に姿勢を変更
sprite.x = 40;
sprite.y = 90;
sprite.rotation = -30;

stage.addChild(sprite);

// スプライトの現在の姿勢を反映した行列を取得
var mtx = sprite.transform.matrix;

// 座標を変換
var l_pos : Point = new Point(10,20);
var g_pos : Point = mtx.transformPoint(l_pos);

// ベクトルを変換
var l_vec : Point = new Point(1,0);
var g_vec : Point = mtx.deltaTransformPoint(l_vec);

// 結果
trace("POS x : " + g_pos.x + " y : " + g_pos.y);
trace("VEC x : " + g_vec.x + " y : " + g_vec.y);
 
 

 

グローバル座標からローカル座標へ変換する
 


■グローバル座標からローカル座標へ変換する

Flashのスクリーン上の座標をグローバル座標と呼ぶことにします。どこかにに配置したインスタンスの座標系をローカル座標と呼ぶことにします。
 
 
グローバル座標が、ローカル座標ではどこに当たるかを調べるには globalToLocal() メソッドを使用します。子のインスタンスから呼び出します。
 
インスタンス.globalToLocal ( Point型 );
第01引数 座標をPoint型にして指定
戻り値 変換された座標がPoint型で返ります
 
スクリーン座標 (10,20) がスプライトのローカル座標上でどこに来るか調べる

var sprite= new Sprite();

// 適当に姿勢を変更
sprite.x = 40;
sprite.y = 90;
sprite.rotation = -30;

stage.addChild(sprite);

var g_pos : Point = new Point(10,20);
var l_pos : Point = sprite.globalToLocal(g_pos);

trace("x : " + l_pos.x + " y : " + l_pos.y);
 
■ローカルベクトルからグローバルベクトルへ変換する

おまけですが、行列情報を使って求めることもできます。座標ではなくベクトルを変換したい場合は、こちらを使います。
 
行列を使って、座標とベクトルをグローバルからローカルへ変換する

var sprite= new Sprite();

// 適当に姿勢を変更
sprite.x = 40;
sprite.y = 90;
sprite.rotation = -30;

stage.addChild(sprite);

// スプライトの現在の姿勢を反映した行列を取得して逆行列にする
var mtx = sprite.transform.matrix;
mtx.invert();

// 座標を変換
var g_pos : Point = new Point(10,20);
var l_pos : Point = mtx.transformPoint(g_pos);

// ベクトルを変換
var g_vec : Point = new Point(1,0);
var l_vec : Point = mtx.deltaTransformPoint(g_vec);

// 結果
trace("POS x : " + l_pos.x + " y : " + l_pos.y);
trace("VEC x : " + l_vec.x + " y : " + l_vec.y);
 
 

 

インスタンスと点の当たり判定を調べる
 

サンプルをダウンロード
 


■インスタンスと点の当たり判定を調べる

インスタンスとの当たり判定を調べるには hitTestPoint() メソッドを使用します。
 
「当たり判定を取りたいインスタンス」から呼び出します。
 
インスタンス.hitTestPoint ( x 座標 , y 座標 , true か false );
第01引数 x 座標
第02引数 y 座標
第03引数 true でインスタンスの形状通りに当たりを取るか、falseで矩形での当たり判定を取るか
戻り値 当たっていれば true 当たっていなければ false
 
■第03引数 形状通りの当たり判定を調べるか?

第03引数が、true であれば形状どおりのピクセルでの当たり判定を取ります。false であれば、矩形として当たり判定が取られます。
 
true false
 
使用例です。
 
インスタンス "mc" とマウス座標とで当たり判定を取る

addEventListener(Event.ENTER_FRAME,function(event){

	if(mc.hitTestPoint(stage.mouseX,stage.mouseY,true)){
		// 当たりあり
	}else{
		// 当たりなし
	}

});
 
 

 

インスタンス同士の当たり判定を調べる
 

サンプルをダウンロード
 


■インスタンス同士の当たり判定を調べる

インスタンス同士の当たり判定を調べるには hitTestObject() メソッドを使用します。
 
「当たり判定を取りたいインスタンス」から呼び出して、引数に「もう片方のインスタンス」を指定します。
 
インスタンス.hitTestObject ( インスタンス );
第01引数 別のインスタンス
戻り値 当たっていれば true 当たっていなければ false
 
インスタンス同士の当たり判定は、描画矩形での判定で取られます。
 
 
使用例です。
 
インスタンス "mc1" とインスタンス "mc2" とで当たり判定を取る

addEventListener(Event.ENTER_FRAME,function(event){

	if(mc1.hitTestObject(mc2)){
		// 当たりあり
	}else{
		// 当たりなし
	}

});
 
 

 

座標下と当たるインスタンスをまとめて取得する
 

サンプルをダウンロード
 


■座標下と当たるインスタンスをまとめて取得する

座標下と当たりのあるインスタンスを配列にして一括で取得するには getObjectsUnderPoint() メソッドを使用します。
 
呼び出したインスタンスを含む子階層のすべてのインスタンスと判定を取ることができます。
 
インスタンス.getObjectsUnderPoint ( Point型 );
第01引数 座標をPoint型にして指定
戻り値 Array 型で奥から順番にソートされています
 
マウス座標下にあるインスタンスをまとめて取得する

addEventListener(Event.ENTER_FRAME,function(event){

	var pos = new Point(stage.mouseX , stage.mouseY);
	var list : Array = stage.getObjectsUnderPoint(pos);
});
 
配列に入っているデータは、インスタンスが持つ Shape オブジェクトが格納されます。インスタンスにアクセスする場合は parent プロパティから参照できるようです。
 
インスタンスを取得

var i;
var list = stage.getObjectsUnderPoint(new Point(0,0));
for(i=0;i < list.length;i++){
	var shape : Shape = list[i];
	var obj : DisplayObject = shape.parent;
}
 
奥から順番に格納されるため、配列の最後にはいっているデータが、もっとも手前に来るインスタンスである事がわかります。
 
最前面のインスタンスを取得

var list = stage.getObjectsUnderPoint(new Point(0,0));
var shape : Shape = list[list.length-1];
if(shape)  trace(shape.parent);
 
セキュリティ上アクセスできないインスタンスは、配列から省かれます。
 
 



HAKUHIN's home page バナー http://hakuhin.jp/
(c) Hakuhin & 日新礼符 2002-2011 解像度1024×768以上 IE8.0以上推奨
/ 閲覧中: