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

第61回StarlingフレームワークでStage3Dを試す

「Starling」は、Flash Player 11の新しい描画機能「Stage3D」にもとづいてつくられた2次元の描画用フレームワークだ。ハードウェアの「GPU」を用いることにより、速くて滑らかな描画ができる[1]⁠。オープンソースのフレームワークなので、あらかじめダウンロードしてインストールしておかなければならない。

Starlingフレームワークのインストール方法については、FumioNonaka.comStarlingフレームワークをインストールするをお読みいただきたい。また、Flash Player 11でパブリッシュするため、今回からFlash Professional CS6を用いることにする(ただし、Flash Professional CS5とCS5.5については、機能拡張によりFlash Player 11での書出しはできる。詳しくは、Flash CS5/CS5.5でFlash Player 11のSWFを書出す参照⁠⁠。

今回を含めた全3回を使って、Starlingフレームワークの基本的な使い方についてご説明しよう。まずは、Starlingフレームワークを用いたスクリプトの組立て方、およびStage3Dへの簡単な描画とアニメーションから始める。

StarlingフレームワークとStage3D

Starlingフレームワークで表示するオブジェクトは、Flashコンテンツの(表示リストがつくられる)ステージとは別のStage3Dの画面に描かれる。そして、Stage3DのレイヤーがあるのはFlashのステージの奥だ。つまり、StarlingにかぎらずStage3Dのコンテンツは、すべてFlashコンテンツの後ろに置かれることになる図1⁠。

図1 StarlingコンテンツはFlashのステージの背面に置かれる
StarlingコンテンツはFlashのステージの背面に置かれる

さて、Stage3Dは文法こそActionScript 3.0にしたがうものの、プログラミングの考え方はアセンブラ(機械語)に近い。そのため、新しい言語といってよい。いい方を換えれば、機械語に近いレベル(⁠⁠低レベル」という)で処理することにより、描画を速めるのがStage3Dだ。そのため、表示リストの階層や、フレームベースのアニメーションといった仕組みはない。

Starlingには、SpriteMovieClipといったクラスがあり、addChild()メソッドも使える。また、addEventListner()メソッドENTER_FRAMEイベントのリスナーを加えることもできる。これまでのActionScript 3.0と似た感覚でStage3Dによる2次元の描画を扱えるのがStarlingフレームワークなのだ。

Starlingフレームワークの表示リストを組立てるには、まずFlashコンテンツのメインタイムラインに当たる最上位の表示オブジェクトをつくらなければなない。そして、Flashのタイムラインにオブジェクトを置いても、Stage3Dには描かれない。だから、Starlingフレームワークの表示オブジェクトをつくるスクリプトは、フレームアクションに書いたのでは勝手が悪い[2]⁠。

したがって、Starlingフレームワークのメインタイムラインとなる表示オブジェクトは、クラスとして定める。このようなクラスを、表示リストのrootにちなんで「ルートクラス」と呼ぶことにしよう。Starlingフレームワークのルートクラス(名前はMySpriteとした)は、つぎのような組立てを基本とする。

package  {
  import starling.display.Sprite;
  public class MySprite extends Sprite {
    public function MySprite() {
      // 処理内容
    }
  }
}

ぱっと見、Flashの表示オブジェクトを定義するクラスと変わらない。ただし、継承extendsするスーパークラスの完全修飾名がflash.display.Spriteではなく、starling.display.Spriteであることに注意してほしい(⁠⁠完全修飾クラス名」については、第22回MovieClipシンボルにクラスを定義するで説明した⁠⁠。Stage3DにつくられるStarlingフレームワークの表示リストには、Starlingの表示オブジェクトしか加えられないからだ。

StarlingフレームワークにはSpriteクラスのほかにも、FlashのActionScript 3.0定義済みと同じ名前のクラスがいくつも備わっている。これらのクラスは、これまでのActionScript 3.0と同じ感覚で書いたステートメントを解釈し、Stage3Dの処理に置換えて命じてくれる。いわば、標準のActionScript 3.0とStage3Dとの間の通訳なのだ。

ルートクラスのActionScript(AS)ファイルと同じ場所に置いたFlashムービー(FLA)ファイルのフレームアクションには、Starlingフレームワークを初期化するステートメントが3行だけ書き加えられる(スクリプト1⁠⁠。まず、Starlingクラスimport宣言したら、つぎにStarlingインスタンスをつくる。メソッドの引数はルートクラスとFlashのStageオブジェクトDisplayObject.stageプロパティの2つだ。そして、Starling.start()メソッドを呼び出すと、Starlingフレームワークの描画が始まる。

スクリプト1 Starlingフレームワークを初期化するフレームアクション
// フレームアクション: メインタイムライン
import starling.core.Starling;
var myStarling:Starling = new Starling(MySprite, stage);
myStarling.start();

この3行のフレームアクションは、ルートクラスの名前を除けば、ほぼお決まりといえる。したがって、次回以降もとくに説明しないかぎり、FLAファイルのメインタイムラインにはこのスクリプト001が書かれているものと考えてほしい。

QuadオブジェクトをStage3Dで表示する

StarlingフレームワークのSpriteクラスは、FlashのActionScript 3.0定義済みクラスと違って、使い途がかなり絞り込まれている。具体的には、表示リストに子の表示オブジェクトをもつことに徹し、Spriteインスタンスそのものには直接描画できない。

そこで、矩形として描かれるStarlingのQuadオブジェクトをつくって、Spriteを継承したルートクラスのインスタンスの表示リストに子として加える。Quadクラスのコンストラクタメソッドには、引数として幅と高さ、およびRGBカラーの数値を渡す。ちなみに、QuadオブジェクトはSpriteとは逆に、子インスタンスはもてない。

new Quad(幅, 高さ, RGBカラー)

つぎのスクリプト2に定めたStarlingルートクラス(MySprite)は、50×50ピクセルの青い矩形をQuadオブジェクトでつくり、子として表示リストに加えたうえで座標(50, 50)の位置に表示する図2⁠。Quadという新しいクラスさえ知れば、スクリプトの説明は要らないだろう。

スクリプト2 青い矩形のQuadインスタンスを表示するStarlingルートクラスの定義
// ActionScript 3.0クラス定義ファイル: MySprite.as
package  {
  import starling.display.Sprite;
  import starling.display.Quad;
  public class MySprite extends Sprite {
    private var nUnit:Number = 50;
    private var nColor:uint = 0x0000FF;
    private var instance:Quad;
    public function MySprite() {
      instance = new Quad(nUnit, nUnit, nColor);
      addChild(instance);
      instance.x = nUnit;
      instance.y = nUnit;
    }
  }
}
図2 青い矩形のインスタンスが表示される
図2 青い矩形のインスタンスが表示される

Flash Professional CS6で[ムービープレビュー]を見るには、前述のとおりStarlingフレームワークが正しくインストールされていなければならない(前出Starlingフレームワークをインストールする参照⁠⁠。⁠ActionScript 3.0の詳細設定]のほか、⁠ハードウェアアクセラレーション]も見落としがちなので注意してほしい図3。なお、筆者の環境は最新のFlash Player 11.3に対応させている。その方法についてはFlash Professional CS6でFlash Player 11.3のSWFを書出すをご覧いただきたい⁠⁠。

図3 ⁠パブリッシュ設定][ハードウェアアクセラレーション]を定める
図3 [パブリッシュ設定]で[ハードウェアアクセラレーション]を定める

Quadオブジェクトをアニメーションで回す

Stage3Dを静止画で見ても意味がない。Quadオブジェクトを回すアニメーションにしてみよう。加えるスクリプトは、ほぼ想像どおりだろう。書替えたStarlingルートクラス(MySprite)の定義が、つぎのスクリプト3だ。

スクリプト3 青い矩形のQuadインスタンスを回転するStarlingルートクラスの定義
// ActionScript 3.0クラス定義ファイル: MySprite.as
package  {
  import starling.display.Sprite;
  import starling.display.Quad;
  import starling.events.Event;
  public class MySprite extends Sprite{
    private var nUnit:Number = 50;
    private var nColor:uint = 0x0000FF;
    private var instance:Quad;
    public function MySprite() {
      instance = new Quad(nUnit, nUnit, nColor);
      addChild(instance);
      instance.x = nUnit;
      instance.y = nUnit;
      addEventListener(Event.ENTER_FRAME, rotate);
    }
    private function rotate(eventObject:Event):void {
      instance.rotation += 0.1;
    }
  }
}

2つ注意しておこう。第1は、Eventクラスがstarling.eventsパッケージに属していることである。ここでも、StarlingフレームワークによるStage3Dへの通訳が働いている。Stage3Dにはもともとない、フレームレートによる描画の更新というイベントを、Starlingが独自につくっているのだ。

第2は、DisplayObject.rotationプロパティの単位だ。DisplayObjectはもちろんstarling.displayパッケージのクラスで、ActionScript 3.0定義済み(flash.display.DisplayObject)とは異なり、角度をラジアンで定めている。Starlingフレームワークは、角度の単位をラジアンに統一しているのだ。

さて、アニメーションを確かめると、確かにQuadインスタンスが回る。ただし、オブジェクトの左上角の基準点が回転の中心になっている図4⁠。これをオブジェクトの中心で回るように改めたい。

図4 Quadインスタンスが左上角の基準点を中心にして回る
図4 Quadインスタンスが左上角の基準点を中心にして回る

Flashの定義済みActionScript 3.0であれば、Spriteインスタンスに入れ子にして子インスタンスの位置をずらすか、Matrixクラスで座標変換をかけるところだ。けれど、Starlingフレームワークではプロパティで変形の中心点が動かせる。

QuadインスタンスのDisplayObject.pivotXDisplayObject.pivotYプロパティで、回転の中心をQuadインスタンスの矩形の真ん中にずらしたのが、つぎのスクリプト4だ。なお、クラスのコンストラクタメソッドに直接書き加えた初期化のステートメントも増えてきたので、初期化のメソッド(initialize())として別に設けた。⁠ムービープレビュー]を確かめると、Quadインスタンスはその真ん中を中心点にして、アニメーションで回る図5⁠。

スクリプト4 青い矩形のQuadインスタンスを中心で回転するStarlingルートクラスの定義
// ActionScript 3.0クラス定義ファイル: MySprite.as
package  {
  import starling.display.Sprite;
  import starling.display.Quad;
  import starling.events.Event;
  public class MySprite extends Sprite{
    private var nUnit:Number = 50;
    private var nColor:uint = 0x0000FF;
    private var instance:Quad;
    public function MySprite() {
      initialize();
    }
    private function initialize():void {
      instance = new Quad(nUnit, nUnit, nColor);
      addChild(instance);
      instance.x = nUnit;
      instance.y = nUnit;
      instance.pivotX = instance.width / 2;
      instance.pivotY = instance.height / 2;
      addEventListener(Event.ENTER_FRAME, rotate);
    }
    private function rotate(eventObject:Event):void {
      instance.rotation += 0.1;
    }
  }
}
図5 Quadインスタンスが真ん中を中心点にして回る
図5 Quadインスタンスが真ん中を中心点にして回る

前掲スクリプト4は、新しいプロパティを使ったことを除けば、いつもどおりのActionScript 3.0の書き方だ。しかし、そのおなじみのプロパティやメソッドは、Starlingフレームワークで同じ名前のクラスに備わる別ものだということを改めて確かめておこう。つぎの表1には、スクリプト4で用いたおもなプロパティやメソッドが定められたStarlingのクラスを掲げた。

表1 ActionScript 3.0とStarlingフレームワークで名前は同じでも異なるプロパティやメソッドなど
プロパティや
メソッドなど
クラス
ActionScript 3.0定義済みStarlingフレームワーク
x/y/width/height/
stageプロパティ
flash.display.DisplayObject starling.display.DisplayObject
addChild()メソッド flash.display.DisplayObjectContainer starling.display.DisplayObjectContainer
addEventListener()
メソッド
flash.events.EventDispatcher starling.events.EventDispatcher
enterFrameイベント flash.display.DisplayObject starling.display.DisplayObject
ENTER_FRAME定数 flash.events.Event starling.events.Event

StarlingルートクラスからStageを参照する

本稿の結びとして、Quadインスタンスをステージ中央に置いてみる。Stageオブジェクトの参照は、DisplayObject.stageプロパティから得られる表1参照⁠⁠。もちろん、StageもDisplayObjectもStarlingフレームワークのクラスだ。しかし、初期化のメソッド(initialize())をつぎのように書替えただけでは足りない。

private function initialize():void {
  instance = new Quad(nUnit, nUnit, nColor);
  addChild(instance);
  // instance.x = nUnit;
  instance.x = stage.stageWidth / 2;
  // instance.y = nUnit;
  instance.y = stage.stageHeight / 2;
  instance.pivotX = instance.width / 2;
  instance.pivotY = instance.height / 2;
  addEventListener(Event.ENTER_FRAME, rotate);
}

[ムービープレビュー]を試すと、つぎのようなランタイムエラー#1009が示されてしまう。これはDisplayObject.stageプロパティの値がnullだからだ。

TypeError: Error #1009: nullのオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。

前掲スクリプト1のフレームアクションで、Starlingインスタンスをつぎのようなコンストラクタメソッドの呼出しによりつくった。すると、Starlingフレームワークの初期化が始まり、第1引数のルートクラス(MySprite)のインスタンスがつくられる。つまり、Starlingルートクラスのコンストラクタが呼び出されるということだ。ところが、このときはまだStageを頂点とするStarlingフレームワークの表示リストに、ルートクラスのインスタンスは加わっていない。

var myStarling:Starling = new Starling(MySprite, stage);

Stageの表示リストに加わる前にDisplayObject.stageプロパティを参照すれば値がnullになる。これは定義済みActionScript 3.0でも同じ約束だ。そして、対処の仕方もActionScript 3.0の原則どおりでよい。DisplayObject.addedToStageイベント(定数Event.ADDED_TO_STAGEでインスタンスがStageの表示リストに加わるのを待って、初期化のメソッド(initialize())を呼び出せばよい。その処理を加えたのが、つぎのスクリプト5だ。

スクリプト5 青い矩形のQuadインスタンスをステージの中心で回転するStarlingルートクラスの定義
// ActionScript 3.0クラス定義ファイル: MySprite.as
package  {
  import starling.display.Sprite;
  import starling.display.Quad;
  import starling.events.Event;
  public class MySprite extends Sprite{
    private var nUnit:Number = 50;
    private var nColor:uint = 0x0000FF;
    private var instance:Quad;
    public function MySprite() {
      addEventListener(Event.ADDED_TO_STAGE, initialize);
    }
    private function initialize(eventObject:Event):void {
      instance = new Quad(nUnit, nUnit, nColor);
      addChild(instance);
      instance.x = stage.stageWidth / 2;
      instance.y = stage.stageHeight / 2;
      instance.pivotX = instance.width / 2;
      instance.pivotY = instance.height / 2;
      addEventListener(Event.ENTER_FRAME, rotate);
    }
    private function rotate(eventObject:Event):void {
      instance.rotation += 0.1;
    }
  }
}

コンストラクタメソッドからいきなり初期化のメソッド(initialize())を呼び出さずに、DisplayObject.addedToStageイベントのリスナーメソッドとして登録した。すると、リスナーはインスタンスがStageの表示リストに加わったとき呼び出される。そうすれば、DisplayObject.stageプロパティは正しくStageオブジェクトを参照できる。なお、メソッドをリスナーにしたため、引数にイベントオブジェクト(eventObject)を加えた。これで、Quadインスタンスはステージ中央に置かれて、回転する図6⁠。

図6 Quadインスタンスがステージ中央に置かれて回る
図6 Quadインスタンスがステージ中央に置かれて回る

次回は、Starlingフレームワークに[ライブラリ]のビットマップからつくったインスタンスを置き、ドラッグしてみたい。マウスのイベントの扱いは、そのつぎの回でも解説することになるだろう。

ところで、本連載もついに60回を超えた。⁠初級者を対象」に始めた解説が、クラスやフレームワークを扱うまでになった。思えば遠くにきた心境だ。編集部とも相談したところ、当初の目的はほぼ達したのではないかという結論に至った。そこで、本連載は後2回あるStarlingフレームワークの解説をもって、一旦閉じることになった。ここまで読んでいただいた読者に感謝するとともに、残り2回のおつき合いをぜひお願いしたい。

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

おすすめ記事

記事・ニュース一覧