ActionScript 3.0で始めるオブジェクト指向スクリプティング

第34回 3次元空間における回転

この記事を読むのに必要な時間:およそ 3.5 分

ビットマップのインスタンスを動的に配置する

つぎに,回すインスタンスを予めタイムラインに置かず,動的につくることにする。そのためには,[ライブラリ]のビットマップに[クラス]を設定しておく必要がある。[ライブラリ]でビットマップを選んだら,[ビットマッププロパティ]ダイアログボックスを開く(オプションポップアップまたはショートカットメニューから[プロパティ]もしくは[ライブラリ]のプロパティボタン⁠⁠。[ActionScript用に書き出し]をチェックしたら,[クラス]を入力する。クラス名は「Image0」としよう図4上図⁠。

図4 [ビットマッププロパティ]ダイアログボックスで[クラス]を設定

図4 [ビットマッププロパティ]ダイアログボックスで[クラス]を設定

図4 [ビットマッププロパティ]ダイアログボックスで[クラス]を設定

今回,Image0というクラスは定義していない。また,そのつもりもない。すると,定義されていないクラスを「自動生成」する旨の警告が表れる図4下図⁠。[OK]ボタンをクリックすれば,その名前で空のクラスが自動的につくられるという仕組みだ。そのクラスは空ではあっても,[ビットマッププロパティ]ダイアログボックスに[基本クラス]としてデフォルト入力されているBitmapDataクラスを継承する。BitmapDataはビットマップを扱うクラスなので,そのためのプロパティやメソッドが使える。

ひとつ注意しなければならないのは,BitmapDataがDisplayObjectクラスを継承しないことだ図5⁠。DisplayObjectまたはそのサブクラスのインスタンスでなければ,インスタンスをタイムラインに加えて表示するDisplayObjectContainer.addChild()メソッドの引数として渡せない。つまり,BitmapData(およびそのサブクラスの)インスタンスは,そのままではタイムラインに表示できない。

図5 BitmapDataはDisplayObjectクラスを継承しない

図5 BitmapDataはDisplayObjectクラスを継承しない

そこで,DisplayObjectクラスを継承するBitmapクラスのコンストラクタメソッドに,ビットマップの(BitmapData)インスタンスを引数として渡す。そうすると,Bitmapインスタンスは,引数に受取ったBitmapDataインスタンスのビットマップイメージをもつ。このBitmapインスタンスをDisplayObjectContainer.addChild()メソッドの引数にして,ビットマップイメージをタイムラインに置けばよい図6⁠。

var myBitmap:Bitmap = new Bitmap(new Image0(0, 0));
addChild(myBitmap);

図6 ビットマップのイメージをもったBitmapインスタンスがタイムラインに配置

図6 ビットマップのイメージをもったBitmapインスタンスがタイムラインに配置

このフレームアクションでひとつ注目してほしいのは,ビットマップに設定したクラス(Image0)のコンストラクタにふたつの0を引数として渡していることだ。これはスーパークラスBitmapDataのコンストラクタが,インスタンスの幅と高さを必須の引数としていることに対応する。

もっとも,サブクラス(Image0)から渡す引数はともに0でよく,インスタンスを生成すれば[ライブラリ]に納めたビットマップの幅と高さが自動的に設定される。だとすると,わざわざ引数を求める意味がない。そのような指摘を反映して,Flash Professional CS5では,これらふたつの引数は省くことができるようになった※2⁠。

前掲スクリプト1に修正を加えよう。[ライブラリ]のビットマップイメージを動的に配置して,インスタンス中心からマウスポインタまでの水平位置に応じてビットマップイメージを水平に回すフレームアクションがつぎのスクリプト2だ。

スクリプト2 動的に配置したビットマップイメージをマウスポインタの水平位置に応じて水平回転

// タイムライン: メイン
// [ライブラリ]のビットマップに[クラス]としてImage0を設定
var mySprite:Sprite = new Sprite();   // Spriteインスタンスを生成
var myBitmap:Bitmap = new Bitmap(new Image0(0, 0));
var nX:Number = stage.stageWidth / 2;
var nDeceleration:Number = 0.3;
mySprite.x = nX;
mySprite.y = stage.stageHeight / 2;
myBitmap.x = -myBitmap.width / 2;   // Bitmapインスタンスの位置合わせ
myBitmap.y = -myBitmap.height / 2;   // 親Spriteインスタンスの基準点が中心にくるように
addChild(mySprite);
mySprite.addChild(myBitmap);   // Bitmapインスタンスは親Spriteインスタンスの入れ子にする
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
  var nRotationY:Number = mySprite.rotationY + (mouseX - nX) * nDeceleration;
  mySprite.rotationY = xGetDegrees(nRotationY);
}
function xGetDegrees(nDegrees:Number):Number {
  nDegrees += 180;
  nDegrees %= 360;
  nDegrees += 360;
  nDegrees %= 360;
  nDegrees -= 180;
  return nDegrees;
}

最初のステートメントで,Spriteインスタンスを生成していることに気づくだろう。ビットマップイメージをもったBitmapインスタンスは,そのSpriteインスタンスに入れ子にした。なぜなら,Bitmapインスタンスの基準点が,左上隅にあって動かせないためだ。つまり,Bitmapインスタンスを直接水平に回せば,左端が軸になってしまう。そこで,親(Sprite)インスタンスに入れ子にしたうえで,親の基準点が中心にくるようにBitmapインスタンスの位置を整えている※3⁠。

これで,[ライブラリ]で[クラス](Image0)を設定したビットマップのイメージが,SpriteとBitmapのインスタンスの入れ子となって配置され,イメージの中心からマウスポインタの水平位置に応じて水平に回転する前掲図1参照⁠。3次元空間における回転は,さらに次回も引続きお題にする。

※2
[ライブラリ]のビットマップに自動設定したクラスに渡す引数参照。
※3
なお,BitmapDataクラスには位置座標のプロパティはない(前述のとおり,DisplayObjectクラスを継承しないので⁠⁠。よって,ビットマップイメージをBitmapインスタンスの中で位置合わせすることはできない。

今回解説した次のサンプルファイルがダウンロードできます。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書