「Starling」は、Flash Player 11の新しい描画機能「Stage3D」にもとづいてつくられた2次元の描画用フレームワークだ。ハードウェアの「GPU」を用いることにより、速くて滑らかな描画ができる[1] 。オープンソースのフレームワークなので、あらかじめダウンロードしてインストールしておかなければならない。
Starlingフレームワークのインストール方法については、FumioNonaka.com「Starlingフレームワークをインストールする 」をお読みいただきたい。また、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への簡単な描画とアニメーションから始める。
[1] 「GPU」( Graphics Processing Unit)は、コンピュータの処理の中でも負荷が高くパフォーマンスに影響する画像処理の演算を扱うプロセッサだ。単に画面を描くことだけでなく、その前の座標空間における変換やカラーの演算など描画に伴う大量の処理までCPUに代わって行う。
そして、「 Stage3D」は、GPUを使うことによって描画の処理を飛躍的に高める技術だ。Flash Player 11から備わった。2次元・3次元に限らず、スクリーンの描画を速め、きめ細かで滑らかなアニメーションを実現する。
StarlingフレームワークとStage3D
Starlingフレームワークで表示するオブジェクトは、Flashコンテンツの(表示リストがつくられる)ステージとは別のStage3Dの画面に描かれる。そして、Stage3DのレイヤーがあるのはFlashのステージの奥だ。つまり、StarlingにかぎらずStage3Dのコンテンツは、すべてFlashコンテンツの後ろに置かれることになる(図1 ) 。
図1 StarlingコンテンツはFlashのステージの背面に置かれる
さて、Stage3Dは文法こそActionScript 3.0にしたがうものの、プログラミングの考え方はアセンブラ(機械語)に近い。そのため、新しい言語といってよい。いい方を換えれば、機械語に近いレベル(「 低レベル」という)で処理することにより、描画を速めるのがStage3Dだ。そのため、表示リストの階層や、フレームベースのアニメーションといった仕組みはない。
Starlingには、Sprite やMovieClip といったクラスがあり、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 青い矩形のインスタンスが表示される
Flash Professional CS6で[ムービープレビュー]を見るには、前述のとおりStarlingフレームワークが正しくインストールされていなければならない(前出「Starlingフレームワークをインストールする 」参照) 。[ ActionScript 3.0の詳細設定]のほか、[ ハードウェアアクセラレーション]も見落としがちなので注意してほしい(図3 。なお、筆者の環境は最新のFlash Player 11.3に対応させている。その方法については「Flash Professional CS6でFlash Player 11.3のSWFを書出す 」をご覧いただきたい) 。
図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インスタンスが左上角の基準点を中心にして回る
Flashの定義済みActionScript 3.0であれば、Spriteインスタンスに入れ子にして子インスタンスの位置をずらすか、Matrixクラスで座標変換をかけるところだ。けれど、Starlingフレームワークではプロパティで変形の中心点が動かせる。
QuadインスタンスのDisplayObject.pivotX とDisplayObject.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インスタンスが真ん中を中心点にして回る
前掲スクリプト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インスタンスがステージ中央に置かれて回る
次回は、Starlingフレームワークに[ライブラリ]のビットマップからつくったインスタンスを置き、ドラッグしてみたい。マウスのイベントの扱いは、そのつぎの回でも解説することになるだろう。
ところで、本連載もついに60回を超えた。「 初級者を対象」に始めた解説が、クラスやフレームワークを扱うまでになった。思えば遠くにきた心境だ。編集部とも相談したところ、当初の目的はほぼ達したのではないかという結論に至った。そこで、本連載は後2回あるStarlingフレームワークの解説をもって、一旦閉じることになった。ここまで読んでいただいた読者に感謝するとともに、残り2回のおつき合いをぜひお願いしたい。
今回解説した次のサンプルファイルがダウンロードできます。