Flex SDK で作った外部 swf の中で定義されているクラスを取り出す方法
Flash で外部ファイルを扱う場合、swf へ埋め込む方法と、直接画像ファイル等をロードする方法があります。swf へ埋め込むとコンパイルに時間がかかったり、埋め込んだ swf 自体のサイズが大きくなったりします。外部ファイルをロードする場合、素材自体が丸見えになる他、数が多くなると、サーバーの負荷が上がったりなど。外部ファイルを自作アーカイブ化して、バイナリデータとして読み込んだ場合、音声データの復元に苦労したりします。
外部データをまとめておく方法の 1 つとして、素材用 swf にデータを埋め込んでおき、その swf をロード、swf 内の素材を取得・・・という方法がありますので、方法を書きます。
まずは素材用 swf を作ります。(parts.swf という名前で作ります。) ソース構成は以下。
/ │ Parts.as │ └─mahoutukai │ Crouch.as │ Move.as │ Standby.as │ ├─crouch │ crouch0001.png │ ├─move │ move0001.png │ move0002.png │ move0003.png │ └─standby standby0001.png
■素材用 swf のメインクラス(このクラスをコンパイルします。)
package
{
import flash.display.Sprite;
import mahoutukai.Crouch;
import mahoutukai.Move;
import mahoutukai.Standby;
/**
* 素材
*
* @author asahiufo/AM902
*/
public class Parts extends Sprite
{
/**
* コンストラクタ
*/
public function Parts()
{
Crouch;
Move;
Standby;
}
}
}
■「待機」画像埋め込みクラス
package mahoutukai
{
/*
* 待機
*
* @author asahiufo/AM902
/
public class Standby
{
[Embed(source=“standby/standby0001.png”)]
public var Graphic0001:Class;
}
}
■「移動」画像埋め込みクラス
package mahoutukai
{
/*
* 移動
*
* @author asahiufo/AM902
/
public class Move
{
[Embed(source=“move/move0001.png”)]
public var Graphic0001:Class;
[Embed(source=“move/move0002.png”)]
private var Graphic0002:Class;
[Embed(source=“move/move0003.png”)]
public var Graphic0003:Class;
}
}
■「しゃがみ」画像埋め込みクラス
package mahoutukai
{
/*
* しゃがみ
*
* @author asahiufo/AM902
/
public class Crouch
{
[Embed(source=“crouch/crouch0001.png”)]
public var Graphic0001:Class;
}
}
この素材用 swf からクラス名を取り出すのですが、Flash で作った場合と違って、Flex にはどんな名前で Class が登録されているか分かりません。(Flash だとシンボルのリンケージにクラス名を指定できるらしい。)swf にどんなクラスが含まれているかを調べるには、FlashDevelop のプロジェクトパネルが使えます。
プロジェクトパネルで parts.swf を開いたの図 どうやら、「<パッケージ名>.<クラス名>_<変数名>」という名前で埋め込んだデータのクラスが定義されているみたいです。
クラス名が分かった所で、メインの swf を作ります。
■メインクラス(これをコンパイルします。)
package src
{
import flash.display.Bitmap;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
/**
* メイン
*
* @author asahiufo/AM902
*/
public class Main extends Sprite
{
/**
* コンストラクタ
*/
public function Main()
{
super();
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onComplete);
loader.load(new URLRequest("parts.swf"));
}
/**
* ロード完了イベントハンドラ
*
* @param event イベント
*/
private function _onComplete(event:Event):void
{
var contentLoaderInfo:LoaderInfo = LoaderInfo(event.target);
contentLoaderInfo.removeEventListener(Event.COMPLETE, _onComplete);
// 待機
var Standby0001:Class = Class(contentLoaderInfo.applicationDomain.getDefinition("mahoutukai.Standby_Graphic0001"));
var standbyGr0001:Bitmap = new Standby0001();
standbyGr0001.x = 0;
standbyGr0001.y = 0;
addChild(standbyGr0001);
// 移動
var Move0001:Class = Class(contentLoaderInfo.applicationDomain.getDefinition("mahoutukai.Move_Graphic0001"));
var Move0002:Class = Class(contentLoaderInfo.applicationDomain.getDefinition("mahoutukai.Move_Graphic0002"));
var Move0003:Class = Class(contentLoaderInfo.applicationDomain.getDefinition("mahoutukai.Move_Graphic0003"));
var moveGr0001:Bitmap = new Move0001();
var moveGr0002:Bitmap = new Move0002();
var moveGr0003:Bitmap = new Move0003();
moveGr0001.x = 0;
moveGr0001.y = standbyGr0001.y + standbyGr0001.height;
moveGr0002.x = moveGr0001.x + moveGr0001.width;
moveGr0002.y = moveGr0001.y;
moveGr0003.x = moveGr0002.x + moveGr0002.width;
moveGr0003.y = moveGr0002.y;
addChild(moveGr0001);
addChild(moveGr0002);
addChild(moveGr0003);
// しゃがみ
var Crouch0001:Class = Class(contentLoaderInfo.applicationDomain.getDefinition("mahoutukai.Crouch_Graphic0001"));
var crouchGr0001:Bitmap = new Crouch0001();
crouchGr0001.x = 0;
crouchGr0001.y = moveGr0001.y + moveGr0001.height;
addChild(crouchGr0001);
}
}
} 要約すると、
- parts.swf を Loader で読み込む。
- Loader.contentLoaderInfo.applicationDomain.getDefinition() メソッドでクラスを取得する。
- 取得したクラスを new してインスタンスを作る。
- インスタンスをいじり倒す。
ということです。
クラスさえ取得できれば、あとは new するだけで同じデータのインスタンスをポンポン作れます。夢のようですね!!
おまけですが、今回のサンプルの Move クラスで、
[Embed(source=“move/move0002.png”)]
private var Graphic0002:Class;
として private な Class 型の変数を作ったのですが、このクラスも普通に parts.swf から取得できるみたいです。クラス定義は、受け取る変数名のアクセス修飾子には関係ないみたいです。