FlashPlayerを自作するSWF研究会:UXClip(11)(2/3 ページ)
モバイル向けFlashPlayerの開発は終了してしまった。ならば、FlashPlayerを自作しようというエクストリームな人たちによる勉強会をレポートする
Shapeの基礎
さて、構造が分かったところで、次はどうやって画面に展開していくかという話になる。ここでは、カヤックの荒賀謙作氏が1フレームのSWFをベクターデータとして再現するデモを行った。
SWFでベクターを描画するアクションは3つ存在する。
- moveTo():ポイントの移動
- lineTo():直線を引く
- curveTo():2次ベジェ曲線
例えば、AS3で四角形を書く場合は以下のようなスクリプトになる。
public function drawSquare(): Shape { var shape: Shape = new Shape(); shape.graphics.lineStyle(4, 0x0000ff); shape.graphics.beginFill(0xff0000, 1.0); shape.graphics.moveTo(50, 70); shape.graphics.lineTo(50, 210); shape.graphics.lineTo(190, 210); shape.graphics.lineTo(190, 70); shape.graphics.lineTo(50, 70); addChild(shape); }
本来であればdrawRect()を使用して簡単に記述できるのだが、SWFで使えるアクションのみで定義すると上記のようになる。
では円形はどうか
public function drawMaru(): void { var shape: Shape = new Shape(); shape.graphics.lineStyle(4, 0x0000ff); shape.graphics.beginFill(0xff0000, 1.0); shape.graphics.moveTo(163.60, 163.60); shape.graphics.curveTo(137.30, 190.00, 100.00, 190.00); shape.graphics.curveTo(62.65, 190.00, 36.30, 163.60); shape.graphics.curveTo(10.00, 137.30, 10.00, 100.00); shape.graphics.curveTo(10.00, 62.65, 36.30, 36.30); shape.graphics.curveTo(62.65, 10.00, 100.00, 10.00); shape.graphics.curveTo(137.30, 10.00, 163.60, 36.30); shape.graphics.curveTo(190.00, 62.65, 190.00, 100.00); shape.graphics.curveTo(190.00, 137.30, 163.60, 163.60); addChild(shape); }
非常に回りくどいことをしているが、本来はこれもまたdrawCircle()で置き換えられる部分だ。円や楕円はベジェ曲線を利用して分解して表現できる。
荒賀氏によれば、swfdumpを使用するとこれら分解されたシェイプを得ることができるので、そこから別の形へコンバートしていけるという。
では自分でバイナリを解析してコンバートする場合は、どのようにアプローチするのだろうか?
答えはShapeタグを読んでいくところにある。Shapeタグは、
- DefineShape
- DefineShape2
- DefineShape3
- DefineShape4
の4種類があり、数字が大きくなるにつれてSWFのバージョンが上がる。そしてその中は、
- Header
- ShapeId
- ShapeBounds
- Shapes
が格納されている。HeaderにはTag typeが格納されており、基本的な位置情報はShapeBoundsに格納されている。描画情報がShapeに格納されているのだが、それがさらに以下のように分かれている。
- FillStyles
- LineStyles
- NumFillBits
- NumLineBits
- ShapeRecords
Flashを触ったことがある人なら分かるが、Flashは塗りと線に分かれていて、それぞれで色を設定することができる。また、線は線種をいくつか設定することができるようになっている。
また、塗りに関してはグラデーション(線形、円形)のほか、ビットマップをタイリングすることもできる。これらを解析し、別のプログラムの描画方法へ置き換えていくのだ。デモではJavaScriptへの置き換えなどが行われていた。
アクションスクリプト実行処理系
そして最後にアクションの処理だ。
例えばフレームアクションを設定した場合、これはどのタイミングで実行されるべきなのだろうか? サイバーエージェントの森野氏による解説が行われた。
Flash Liteでアクションを設定する場所は、フレームとボタンの2つがある。フレームアクションはShowFrame時に実行する。アクション自体はDoActionに格納されている。
ボタンアクションはDefineButton内に格納されている。キーボードイベントなどはDefineButton2に格納されている。これらの詳細はAdobeの公式ドキュメントにも記されているので、詳しくはここを参照してみるといいだろう。
しかし、公式ドキュメントでも完全とはいえず、実装時にハマるポイントがいくつか存在する。例えば複数のアクションが設定されていたとき、実行順序はどうなるのか、またそのタイミングはどうなるのだろうか?
直接座標をコントロールされたとき、レンダリングはどのように処理していけばいいのだろうか? このあたりの仕様ははっきりとしておらず、地道に観察していくしかない。
まずはAdobeのPlayerで再生してみて、その挙動をよく観察すること。場合によっては「このアクションを実行するだけ」などというテスト用SWFを再生してみるのもいいだろう。そして、フレームレートを下げるのも手だ。その結果仮説を立てて実装。これを検証するというステップを繰り返す。
普段何げなく書いている簡単なアクションでも、展開時はこれほどまでに苦労するのだなと実感したプレゼンだった。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
Copyright © ITmedia, Inc. All Rights Reserved.