最先端のFlasherの方々は、あまりステージにムービークリップやコンポーネントを配置したりしないのかもしれないが、個人的にはステージにグラフィックやボタンなどを配置することが多い。
それらをドキュメントクラスから使う場合、どうしたらいいのかわからなくてかなり悩んだ。
たとえば、以下のような画面があるとする。
![]()
ステージ上にButtonとTextInputコンポーネントを配置し、それぞれ、
btn,inputtというインスタンス名とする。
ドキュメントクラスは、Main.asとする
パブリッシュ設定から、「ステージのインスタンスを自動宣言」をチェックしている場合(デフォルトでON)、ステージに配置したムービークリップおよびコンポーネントは、パブリッシュする際に自動的にオブジェクトのインスタンスが生成される。
Flashでは、ムービークリップシンボル、ボタンシンボル、またはテキストフィールドをステージに配置し、プロパティインスペクタでインスタンス名を割り当てた場合、自動的にそのインスタンス名で変数が宣言され、オブジェクトインスタンスが作成され、そのオブジェクトが変数に格納されます。
この場合、class Mainにおいて、btn,inputに直接アクセスできる。サンプルソースはこちら
[as]
package {
import fl.controls.Button;
import fl.controls.TextInput;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*;
/**
* …
* @author Default
*/
public class Main extends MovieClip {
public function Main() {
btn.addEventListener(MouseEvent.CLICK, btn_click);
trace(btn.label);
}
private function btn_click(e:MouseEvent):void {
input.text = “hoge”;
}
}
}[/as]
しかし、これでは、btn,inputというインスタンスに対し、FlashCSのIDE(内蔵エディタね)やFlashDevelop(外部エディタね)が、btn,inputの型がわからないため、プロパティやイベントハンドラを補完できない。これは非常に不便である。では、Classのメンバーとして次の2行を追加したらどうだろうか。
[as]
var btn:Button;
var input:TextInput;
[/as]
これで、コードの補完はできるようになった。(IDEが変数の型を認識できるため)。AS2.0でもこの方法でよかった。
しかし、今度は、
コンパイルエラー 1151:定義 btn(名前空間 internal)にコンフリクトが存在します。
というエラーになる。
つまり、ステージ中に配置したコンポーネントが自動宣言されており、かつ、クラスの中でも宣言されてしまったため、宣言が衝突しているのである。
自動宣言と手動宣言のコンフリクトについてはvoid element blog: 自動宣言と手動宣言のコンフリクトにも書かれている。
やっぱり、パブリッシュ設定の「インスタンスの自動宣言」のチェックはハズすべきか。とりあえずハズしてみる。
![]()
すると、今度は、
ReferenceError: Error #1056: Main のプロパティ btn を作成できません。
at flash.display::Sprite/flash.display:Sprite::constructChildren()
at flash.display::Sprite$iinit()
at flash.display::MovieClip$iinit()
at Ins$iinit()
という、ランタイムエラーがでるのである。うーん。困った。自動配置すれば、コンフリクトするし、自動配置しなければ、インスタンスが生成されてない(ただステージに置いただけ)ので、アクセスできない(みたい)
かといって、全てをclass内でnewしてaddChildして、座標を設定してlabelを設定して・・というのは効率が悪すぎる。
結局、何がやりたいかというと、
*ステージ上に配置したコンポーネント/ムービークリップをドキュメントクラス内からアクセスしたい
*そのとき、エディタで補完機能が動くように、型宣言を追加したい。
で、いろいろ調べた結果、たどり着いた方法としては、ステージ上に配置したインスタンス名と同じ名前のメンバー変数をドキュメントクラス内で定義する際に、publicを付けてやること。
最終的なコードは、
[as]
package {
import fl.controls.Button;
import fl.controls.TextInput;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.*;
/**
* …
* @author Default
*/
public class Ins extends MovieClip {
public var btn:Button; // ←ここ! publicを付ける
public var input:TextInput; // ←ここ! publicを付ける
public function Ins() {
btn.addEventListener(MouseEvent.CLICK, btn_click);
trace(btn.label);
}
private function btn_click(e:MouseEvent):void {
input.text = “hoge”;
}
}
}[/as]
そうすると、ステージ上に配置したコンポーネント/ムービークリップと融合?した感じになり、クラス内では実体が内のだけれど、ちゃんとステージ上のコンポーネント/ムービークリップにアクセスできるようになり、かつ、型もわかるのでコード補完もできるというわけです。
参考: オーサリング時に配置されたインスタンスの型指定 MovieClipインスタンスとインスタンス名
s.h.log: Flash CS3 – ステージのインスタンスの自動宣言が止められないので
void element blog: 自動宣言と手動宣言のコンフリクト
F-site |
F-site |
Popularity: 25% [?]




