2009年2月1日日曜日

Adobe MAX Japan 2009/AS3でグラフィックス描画

Adobe MAX Japan 2009 に参加。
<!--more-->
{smartads}

Commodore64 や AMIGA を Flash の先祖だとして紹介していた講演が興味深い。Adobe のイベントでメガデモを観る事になるとは!ちなみに Ralph Hauwert という Papervision3D という 3D ライブラリの開発者の方である。氏は rePhlex という、いわばビジュアル版シンセサイザのようなものをもっか開発中のようで、こちらも注目である。

ところで、最近の Flash 環境にはすっかりごぶさたです。今回のイベントがちょうど良いきっかけになったので、超久しぶりに Flash の勉強をやることにします。正味数年ぶりだと思うのでリハビリだなこりゃ。環境は CS3/ActionScript3.0 でいきます。描画周りはそれほど変わってないという認識なので、AS3 がメイン。

<h2>ActionScript によるグラフィックス描画</h2>
まずは ActionScript による単純な描画から。完全にスクリプトのみで、描画を行う事が可能。描画機構も AS3 で大きく刷新されたようである。

以下のコードを新規ドキュメントの 1フレーム目、フレームアクションに記述する。ちなみに AS3 からクリップアクションは記述できなくなった。
<pre lang="Actionscript" line="1">
var sp:Sprite = new Sprite();  //SpriteはMovieClip のタイムライン無し版(軽量)
var bg:Shape = new Shape();  //ShapeはSpriteのaddChildできない版(最軽量)

//表示リストに追加
this.addChild(bg);
this.addChild(sp);

drawBackground(bg.graphics);  //背景Sprite描画
drawSprite(sp.graphics);  //前景Shape描画

// Shapeを移動する(センタリング)
sp.x = (stage.stageWidth-sp.width)/2;
sp.y = (stage.stageHeight-sp.height)/2;

//背景Sprite描画
function drawBackground(g:Graphics) {
var m:Matrix = new Matrix();
m.createGradientBox(stage.stageWidth, stage.stageHeight, 90*Math.PI/180);
g.beginGradientFill(GradientType.LINEAR, [0x000000, 0x666666],[1.0, 1.0], [0, 255], m);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
}

//前景Shape描画
function drawSprite(g:Graphics) {
g.lineStyle(4, 0x000000);
g.beginFill(0xff0000, 0.5);
g.drawEllipse(30, 0, 100, 100);
g.beginFill(0x00ff00, 0.5);
g.drawEllipse(0, 50, 100, 100);
g.beginFill(0x0000ff, 0.5);
g.drawEllipse(60, 50, 100, 100);
g.endFill();
}
</pre>
すると、結果はこうなる:
<script type="text/javascript" src="/js/swfobject/src/swfobject.js"></script>
 <script type="text/javascript">
    swfobject.embedSWF("/wp/wp-content/uploads/2009/02/as30graphicstest1.swf", "swfEmbedded", "250", "250", "9.0.0");
    </script>
<div id="swfEmbedded">
      <p>Alternative content</p>
</div>

ポイントは軽量な Sprite/Shape の導入、表示に追加するには addChild、描画するには各オブジェクトの graphics プロパティ経由あたり。細かい描画メソッドは、何か見ながら書けばよろしかろう。

ちなみに this.addChild() している箇所、this を trace すると [object MainTimeline] が返り、root の trace も結果の表示は一緒なんだけど、root.addChild() しても同じ結果が得られなかったのは不明。だけどとりあえずは良しとする。オブジェクトの identity が見られると良いのだけど。