ActionScriptを使わないFlash勉強会 #1(前日版)

Preview:

Citation preview

クライアントサイドにおける

動的swf生成の可能性と使用例

2011. 4. 23(Sat) ActionScriptを使わないFlash勉強会 #1

speaker: @niwauu

よろしくー

できること やったこと

1

はじめに

お前、だれよ?

にわうう/王子南

twitter: @niwauu web: “王子南交差点” http://libpanda.s18.xrea.com

動的swf生成ネタで主に携帯用のこまごましたものを作っています。

非プログラマ・非デザイナ ただの人です。

うっかり契約してスピーカーになったよ! こんなの絶対(ry

2

お前、だれよ?

FLASH-jpフォーラムに動的swfネタで1回だけ投稿したよ

▪パラメータ埋め込みサンプルと原理の紹介 ▪もう5年前です(でもまだここ経由で一番人が来ます

3

“ iモード用のFLASHにパラメータを送りたい ”

【53】

【21】

お前、だれよ?

4

人気順

【462】FLASH-jpトップページ

はてブでFLASH-jp内 一番人気のスレッドに! やっぱり動的SWF生成だよね

きょうのおはなし

• テーマについて(「クライアントサイドにおける~」)

• FlashLite1.1についてと動的swf生成のモチベーション

• swfバイナリのフォーマットと編集の基本

• 動的swf生成の実例

1. パラメタ渡し・Script Bytecodeの挿入

2. 画像の入れ替え・サイズ変更

3. 画像とアニメーション、サウンドの挿入

4. AS3での戦略とEmbedded Binaryの置換

• まとめ

主に「まめフラスコ」という

自作ソフトウェアでやってることの話です。

5

登場タグ

DefineBitsLossless2 DefineBitsJPEG2 DefineBitsJPEG3 DefineShape DefineSprite DefineSound

DoAction FrameLabel StartSound PlaceObject2 RemoveObject2 ShowFrame End

6

タイトルについて

広義

7

クライアントサイドにおける動的swf生成の可能性と使用例

クライアント側⇔サーバ側 ローカル側⇔ネットワーク側 ユーザ側⇔コンテンツプロバイダ側

生成・素材・再生がクライアント側

▪ サービスに依らずに生成 ▪ ネットワークにつながない自由 ▪ 自分の素材でカスタムswf

8

動的SWF生成ことはじめ

なんで動的にやるの?

▪ FlashLite1.1の制限 1. サイズ(100kB)制限 2. 機能制限 (1) 通信時ボタン押下必須制限 (2) URL値渡し制限 (3) SharedObjectないよ

• 必要なものを必要な分だけ埋め込む • “swfにアクセスする”通信1回で必要な読込をまとめて • ローカルでのデータ設定・保持できないなら

ネットワーク側で面倒見る

9

「FlashLite1.1でやらなきゃいけない」が一番の制限(シェアのせい)

10

まだまだFlashLite1.1

• Flamixer 携帯向けFlash動的生成エンジン http://www.klab.jp/flamixer/

• Tomato swfバイナリ加工pythonライブラリ https://github.com/buhii/tomato

• 日本FlashLite1.1ユーザー会 http://groups.google.com/group/FlashLite11_ja

• ソーシャルゲームに生かすFlash Lite制作テク http://www.atmarkit.co.jp/fsmart/index/flashlite.html @ITの連載

最近目についたものだけでも…

なんで動的にやるの?(そのほかの理由)

• Lite1.1のSWF内で使いやすいデータ形式への シームレスな変換ができる。

11

• 単一ファイル化(外部に読み込むファイルを置かない)

によって取り回しを簡単にする

SWFバイナリの基本

SWFファイルはヘッダとそれに続く複数のタグからなる ヘッダ:バージョン, ファイルサイズ, ステージサイズ,

フレームレート, 総フレーム数,

タグ: Definitionタグ ShapeやMCなどのキャラクタを定義 Controlタグ 定義したキャラクタの取り扱い

SWF全体の流れのコントロール

12

1フレーム目

Header Tag Tag Tag Tag Tag Tag

ShowFrame ShowFrame

2フレーム目

Tag Tag

ShowFrame

End Nフレーム目

DictionaryとDisplayList

13

DefineShape

CharacterID=1

Dictionary IDで管理

DefineShape

CharacterID=2

CharacterID=1

CharacterID=2

PlaceObject2

CharacterID=1 Depth= 3

PlaceObject2

CharacterID=2 Depth= 2

PlaceObject2

CharacterID=1 Depth= 1

DisplayList Depthで管理

Depth=3

Depth=2

Depth=1

定義 配置

ShowFrame

ステージ上に表示 管理用番号にはCharacerIDとDepthがある • 定義したシェイプなどにはIDを振って管理 • ステージに表示するものにはDepthを振って管理

開発のための環境とヒント

0. バイナリエディタ

1. swf_file_format_v10.pdf Adobeによるファイルフォーマット解説。必須

2. Adobe Flash CS* どんなバイナリが生成されるべきかの確認。お手本

3. $ swfmill swf2xml hoge.swf SWFバイナリ内のタグ・パラメータの確認 自前のパーサ・バイナリが正しく作れているか

(4. Sothink Flash Decompiler)

3.の確認ができるグラフィカル版。

14

15

パラメタ埋め込みとその実例

を実行するswfと同等のものを生成する

代入文バイトコード埋め込みによる変数渡し

http://.../hoge.swf?name=niwauu

16

1フレーム目のフレームアクションで

name = “niwauu”;

DoActionタグの生成とベースSWFへのタグ挿入

パラメタ埋め込み動的SWFの例(1) 17

Header Tag Tag Tag Tag Tag

ShowFrame

Tag Tag

End

パラメタ埋め込み動的SWFの例(1) 18

Tag

DoAction Tag

スクリプト

name = “niwauu”;

バイトコード

0x96 0x06 … 0x96 0x08 … 0x1d 0x00

タグ

タグヘッダ

バイト コード

New

Header Tag Tag Tag Tag Tag

ShowFrame

Tag Tag

End

パラメタ埋め込み動的SWFの例(1) 19

Header Tag Tag Tag Tag Tag

ShowFrame

Tag Tag

Tag Tag Tag Tag Tag Tag Tag Tag

DoAction Tag

スクリプト

name = “niwauu”;

バイトコード

0x96 0x06 … 0x96 0x08 … 0x1d 0x00

タグ

End

タグヘッダ

バイト コード

New

• 1フレーム目へのDoActionタグの挿入

1フレーム目

Header

パラメタ埋め込み動的SWFの例(1) 20

Header Tag Tag Tag Tag Tag

ShowFrame

Tag Tag

Header Tag Tag Tag Tag Tag Tag Tag Tag

DoAction Tag

スクリプト

name = “niwauu”;

バイトコード

0x96 0x06 … 0x96 0x08 … 0x1d 0x00

タグ

End

タグヘッダ

バイト コード

New

• 1フレーム目へのDoActionタグの挿入 • 全体のサイズ変更によるSWFヘッダの更新

1フレーム目

Modified

スクリプトのActionシーケンスへの変換

21

name = “niwauu”;

1.「nameに」 2.「niwauuを」 3.「代入しろ」

ActionPush “name” ActionPush “niwauu” ActionSetVariable

Actions

DoActionタグ (TagType=12)

22

Tag Header

Action EndFlag

ACTION RECORD

ACTION RECORD

ACTIONRECORD

payload

(Stringなど)

(ない場合も)

ACTION RECORD HEADER

ActionCode Length

•ActionScript 1, 2のみ •ActionSctipt3はDoABCタグで表現 (DoActionタグは無視される)

UI8 (0x00) (ない場合も)

▋ 実行するActionScriptをバイトコードで表現

ActionScriptのバイトコードのバイナリ表現(1)

23

3f 03 = 0011 1111 0000 0011 0000 0011 0011 1111

Tag Header

16 00 00 00

Tag Type = 12

Tag Length = 22 bytes

ActionCode

Length

96

06

payload

00 6e 61 6d 65 00

ActionPush

payload長

Pushするものは文字列 ‘n’ ‘a’ ‘m’ ‘e’ ‘¥0’

(→つづく)

ActionPush “name” ActionPush “niwauu” ActionSetVariable

3f 03 16 00 00 00 96 06 00 6e 61 6d 65 00 96 08 00 6e 69 77 61 75 75 00 1d 00

ActionScriptのバイトコードのバイナリ表現(2)

24

ActionCode

Length

1d

payload

00

ActionSetVariable

(なし)

(なし)

Action EndFlag

ActionEnd タグ終わり

ActionCode

Length

payload

96

08

00 6e 69 77 61 75 75 00

ActionPush

payload長

Pushするものは文字列 ‘n’ ‘i’ ‘w’ ‘a’ ‘u’ ‘u’ ‘¥0’

(→つづき)

カウントダウン • ある期日までの日数を表示 • 待受画面に表示 センターとか国立2次試験 ⇒共通の需要があるので誰かが作る 私大・他の資格試験・記念日 ⇒個人的・自分で作らないとない

テンプレートSWF + 外部ファイルからパラメタ読み込みでやる?

待受画面⇒ネットワークとSharedObjectの制限

動的SWF生成で制限を超える

25

パラメタ埋め込み動的SWFの例(1)

パラメタ埋め込み動的SWFの例(2)

tbl2swf: リアルタイム時刻表アプリ

NextTrain時刻表形式のテキストファ イルをSWFファイルに変換

26

Lite1.1内で扱いやすくするために 独自データ形式へ変換して埋め込み

『旅ココ』(http://tabikoko.net) さま tbl2swfを使ったマッシュアップwebサービス

待受画面に設定すると最速NextTrain環境(スマホより上)

txt

パラメタ埋め込み動的SWFの例(2)

NextTrain時刻表形式:

27

a:岡山;岡 b:広島;島 c:三島;三

$品川: j6 k6 l6 $新横浜: j17 k15 l16 $小田原: j33 l32 k= $熱海: j42 l36 k=

[MON][TUE][WED][THU][FRI] # 東京 卙多方面(平日のダイヤ) 6: ke00 k05 kb20 jh23 ke26 la36 ke50 k53 j56 7: l06 ke13 jh23 k26 kb33 la36 ke50 j56 22: lh00 jd10 jc47

Bn=“00010003000400060008… Bj=“024002450260026302660… Bt=“kekkbjhkkelakejlk…

パラメタ埋め込み動的SWFの例(3)

kif2swf:将棋盤再生アプリ 将棋の棋譜「☗ 7六歩☖3四歩☗2六歩…」 などをグラフィカルに表示 kif形式ファイル(テキストファイル)を読み込み

1ファイル化⇒ブログに挙げるのが楽

HTMLのobjectタグでうまく埋め込まれなくてもSWFへの リンクさえあればブラウザ全画面表示になるけど とりあえずは閲覧できる 読み込みも早い

森信雄七段(日本将棋連盟 プロ棋士)詰将棋ブログでも!

28

txt

29

画像もいじってみよう

画像置換の例

さめがめクローン

• コマの画像をカスタマイズ • FlashLite製のドット絵描きアプリと連携 ⇒携帯だけで自分専用のものが作れる

30

画像のサイズ(縦横)は丌変 透過つき可逆圧縮画像(透過PNG)

DefineBitsLossless2タグを入れ替え

画像置換の例

31

BitmapID=5

DefineBitsLossless2タグ内のCharacterのIDから置換すべき タグを識別、IDを保持したまま画像データ部置換する

BitmapID=5

DefineBitsLossless2 DefineBitsLossless2

BitmapID=5の DefineBitsLossless2タグ

Header Tag Tag Tag Tag Tag Tag Tag Tag

タグ編集

DefineBitsLossless2(Tag type=36)

32

▮画像を定義(可逆なもの。PNG, GIF用) • キャラクターIDでSWF内での識別 • 画像データ部は、

Header

画像データ

CharacterID

Width

Height

BitmapFormat

DefineBitsLossless2(Tag type=36)

33

Header

CharacterID

Width

Height

ColorTableSize パレット色数

ColorTableRGB パレット色情報

Colormap PixelData

パレット番号の羅列 (8bit)

▮画像を定義(可逆なもの。PNG, GIF用) • キャラクターIDでSWF内での識別 • 画像データ部は

BitmapFormat = 3のとき

パレット色情報+パレット番号

の羅列をzlib圧縮(□)したもの BitmapFormat=3 ⇒ 1pixelあたり1Byte

BitmapFormat = 3

DefineBitsLossless2(Tag type=36)

34

Header

BitmapFormat = 5

CharacterID

Width

Height

Bitmap PixelData

ARGBの羅列

(32bit)

▮画像を定義(可逆なもの。PNG, GIF用) • キャラクターIDでSWF内での識別 • 画像データ部は

BitmapFormat = 3のとき

パレット色情報+パレット番号 BitmapFormat = 5のとき

ARGBデータ の羅列をzlib圧縮(□)したもの

BitmapFormat=3 ⇒ 1pixelあたり1Byte BitmapFormat=5 ⇒ 1pixelあたり4Byte

DefineBitsLossless2(Tag type=36)

35

▮画像を定義(可逆なもの。PNG, GIF用) • キャラクターIDでSWF内での識別 • 画像データ部は

BitmapFormat = 3のとき

パレット色情報+パレット番号 BitmapFormat = 5のとき

ARGBデータ の羅列をzlib圧縮(□)したもの

BitmapFormat=3 ⇒ 1pixelあたり1Byte BitmapFormat=5 ⇒ 1pixelあたり4Byte ⇒ 256色以下の場合容量削減のため

BitmapFormat=3(パレット形式)を使う

透過色ない場合はDefineBitsLossless(Tag type=20) を使って透過情報を含めないことで容量削減

Header

BitmapFormat

画像データ

CharacterID

Width

Height

SWF内のBitmap画像の扱い

・画像データの置換⇒DefineBitsLossless2の変更

36

BitmapID

DefineBitsLossless2

SWF内のBitmap画像の扱い

・画像データの置換⇒DefineBitsLossless2の変更 ・画像の配置⇒「画像で塗りつぶした矩形」の配置 ・DefineShapeがコンテナ役、描画領域を決めている ・異なる画像サイズに置換⇒DefineShapeも変更が必要

37

BitmapID BitmapID

ShapeID DefineBitsLossless2 DefineShape

SWF内のBitmap画像の扱い

・画像データの置換⇒DefineBitsLossless2の変更 ・画像の配置⇒「画像で塗りつぶした矩形」の配置 ・DefineShapeがコンテナ役、描画領域を決めている ・異なる画像サイズに置換⇒DefineShapeも変更が必要 ・ステージに配置するのはPlaceObject2 ・ステージ上でのオブジェクトの一意性はDepthで管理

38

BitmapID BitmapID

ShapeID ShapeID

Depth

Stage DefineBitsLossless2 PlaceObject2 DefineShape

Depth

• テキスト埋め込み

単語帳

時間割

• 画像入替

15パズル

ランダム画像表示

ドット絵作成(⇒作業中の絵のサムネイル表示用)

ほかいろいろ作ったもの 39

csv

問題

単語帳Flash生成アプリ『flowermaker』の例

40

もっといろいろのタグをいじる ~『まめフラスコ』のはなし

『まめフラスコ』のはなし

「まちうけメーカーforフラッシュマスコット」

の略から来ています。

41

ユーザの入力からこういうのをつくります ・時間・電波・バッテリ残量などで内容が変わる 携帯待受けとしてはよくあるもの ・画像、台詞、音声、などユーザの用意したものを 埋め込んでオリジナルキャラクターを作成 ・「伺か」的なものを目指して台詞を表すスクリプトや アニメーション定義で似たファイル形式を使用

まめフラスコ:待受Flash生成アプリ

『まめフラスコ』のはなし 42

実は powered

Java VM

¥0¥s[0] こんにち は世界!!

素材 ・画像 ・テキスト

FlashPlayer 搭載端末

まめふら

SWFファイル を生成

まめフラスコ:待受Flash生成アプリ

PythonのJava実装

デスクトップの隅にキャラクターを立たせて 「なんか言うのを眺める」から 「OSの機能やネットワーク通信と連携させたいろいろ」 (例:メール着信確認、簡単なゲーム、サーバ監視)

「伺か」ってなに?

43

約10年で1000体以上、現在でも盛ん、14 体/月 @2011

特徴: • DLLと簡易言語による非常に自由度の高い機能拡張 • ユーザによる盛んな追加キャラクター作成

デスクトップ常駐型マスコットアプリケーション 今でいえばウィジェット(ガジェット)に近い 読み:「うかがか」

インターフェース層の擬人化 好感度システム⇒ラブプラス的な

「伺か」ってなに?

44

こういうのです。

まめフラスコでやっていること

45

• テキスト情報の挿入 • 画像の置換 • 画像の挿入 • ムービークリップの生成・挿入 • サウンドの挿入

• テキストボックスのサイズ変更 • シェイプの色の変更 • SWF背景色の変更

基本キャラクターの変更 46

• キャラクターはMovieClipで表現 • MovieClipの中のダミー画像を置換したい。 • DefineBitsLossless2, DefineShapeを変更する • PlaceObject2は変更なし

a

置換前

置換後

基本キャラクターの変更 47

• あらかじめ埋め込まれたダミー画像の置換 • サイズが変わるので一致するIDのDefineShapeも要置換 • サイズ削減のためJPEG形式に変換しての置換もする • (DefineBitsLossless2⇒DefineBitsJPEG2/3)

DefineBits Lossless2

DefineShape

DefineBits Lossless2

DefineShape

DefineBits JPEG3 or

PNG

BitmapID=N

BitmapID=N ShapeID=M

ARGB JPG

入力

BitmapID=N BitmapID=N

BitmapID=N ShapeID=M

DefineBitsJPEGタグ

DefineBits ⇒encodingを記したJPEGTablesタグとセットで使う

DefineBitsJPEG2⇒ふつうのJPEG DefineBitsJPEG3⇒JPEGデータ+透過情報

DefineBitsJPEG4⇒JPEG3タグの内容+deblockingパラメタ

48

【DefineBitsJPEG2】

タグヘッダ

キャラクターID

画像データ (JPEGそのまま)

タグヘッダ

キャラクターID

画像データ (JPEGそのまま)

【DefineBitsJPEG3】

画像データサイズ AlphaDataOffset

width x height個の α値の羅列を zlib圧縮したもの

正確には「JPEGそのまま」でなく JPEGデータ先頭にEOI, SOIを つけないと画像が赤四角になる

“Before version 8 of the SWF file format, SWF files could contain an erroneous header of 0xFF, 0xD9, 0xFF, 0xD8 before the JPEG SOI marker.”

flash_file_format_v10.pdf(p.148)

DefineBits+JPEGTables時代(Future Splash)の名残り 圧縮テーブルと圧縮データを分けていたので SOI/EOIが2回含まれていた

DefineShapeタグ(Tag type=26)

49

▮シェイプの定義 - 使う塗りのスタイル - 使う線のスタイル - シェイプを構成する線や塗りの集合

Header

ShapeBounds

FillStyles

LineStyles

NumFillBits

NumLineBits

ShapeRecord

ShapeID

Shapes

・画像の配置⇒ 「画像で塗りつぶした矩形」の配置 ・DefineShapeがコンテナ役、 描画領域を決めている

DefineShapeタグ(Tag type=26)

50

:定義するシェイプの境界

ShapeBoundsフィールドで矩形で定義

:シェイプで表示させたい画像 「領域を画像で塗りつぶす。 その画像は(BitmapID)」 FillStylesの中のBitmapIDで指定

:矩形を構成する直線 × 4

ShapeRecordsの中のStraightEdgeReocrdで指定 垂直線:VertLineFlag=0, DeltaX= (移動twips) 水平線:VertLineFlag=1, DeltaY= (移動twips)

• 変更と確認が必要な部分は3つ(▮印) Header

ShapeBounds

FillStyles

LineStyles

NumFillBits

NumLineBits

ShapeRecord

ShapeID

Shapes

DefineShape ShapeID=3

DefineShape内の画像扱いの注意 51

ひとつのDefineShapeタグ内には複数の塗りが定義できる DefineShape⇄DefineBitsLosslessは必ずしも1対1対応でない

• Flashがパブリッシュしたswfをベースとする場合注意 ⇒シンボル化

fillStyle: BitmapID=2

fillStyle: BitmapID=1

BitmapID=2

DefineBits Lossless2

DefineBits Lossless2

BitmapID=1

2

PlaceObject2タグの MATRIX内の TranslateX, TranslateY で指定

DefineShapeタグの FillStyle内の BitmapMatrix内の TranslateX, …で指定

任意の位置への画像を置くには

1. 名前付きMCにして変数埋め込み、スクリプトで位置指定 2. PlaceObject2タグの描画位置を設定 3. DefineShape内の矩形描画位置を指定する

( Shape自身の配置位置は(0, 0) )

52

3

(200, 150)

1

tellTarget(“mc1”) { _x = 200;_y = 150; }

“mc1”

こういうMCを置換で作る

PlaceObject2タグ(Tag type=26)

53

▮ DefineShapeなどで定義した キャラクターをID指定して配置 ・Depthは表示順を表すとともに SWF内のオブジェクトを一意に管理 ・表示位置は TransformMatrix 内の

translateX, translateYで指定 ・NameをつけることでMovieClipに tellTargetでアクセス可能

Header

PlaceFlagMove

Depth

CharacterID

Transform Matrix

Color Transform

Ratio

Name

ClipDepth

ClipActions

これらがあるか

PlaceObject2タグ(Tag type=26)

54

▮ DefineShapeなどで定義した キャラクターをID指定して配置 ・Depthは表示順を表すとともに SWF内のオブジェクトを一意に管理 ・表示位置は TransformMatrix 内の

translateX, translateYで指定 ・NameをつけることでMovieClipに tellTargetでアクセス可能

Header

PlaceFlagMove

Depth

CharacterID

Transform Matrix

Color Transform

Ratio

Name

ClipDepth

ClipActions

これらがあるか

PlaceObject2タグ(Tag type=26)

55

▮ DefineShapeなどで定義した キャラクターをID指定して配置 ・Depthは表示順を表すとともに SWF内のオブジェクトを一意に管理 ・表示位置は TransformMatrix 内の

translateX, translateYで指定 ・NameをつけることでMovieClipに tellTargetでアクセス可能

Header

PlaceFlagMove

Depth

CharacterID

Transform Matrix

Color Transform

Ratio

Name

ClipDepth

ClipActions

これらがあるか

PlaceObject2タグ(Tag type=26)

56

▮ DefineShapeなどで定義した キャラクターをID指定して配置 ・Depthは表示順を表すとともに SWF内のオブジェクトを一意に管理 ・表示位置は TransformMatrix 内の

translateX, translateYで指定 ・NameをつけることでMovieClipに tellTargetでアクセス可能

Header

PlaceFlagMove

Depth

CharacterID

Transform Matrix

Color Transform

Ratio

Name

ClipDepth

ClipActions

これらがあるか

RemoveObject2タグ(Tag type=28)

57

Header

Depth

▮指定したDepthのObjectをステージ上から消去する

CharacterIDでなくDepthで管理

SWFバイナリにはキーフレームという概念がないので

それまでPlaceしたObjectを表示しなくするためには

明示的にRemoveObject2タグで消去する必要がある

この次のフレームでそれまで置いた

ObjectをRemoveする

placeFlagMove = 1 のときは そのdepthのObjectを一旦Removeして 同じDepthに二重Placeしない

PlaceObject2タグ(Tag type=26)

58

Header

PlaceFlagMove

Depth

CharacterID

Transform Matrix

Color Transform

Ratio

Name

ClipDepth

ClipActions

これらがあるか

Depthで管理してるので タグはCharacterIDを知らなくても良い

そのためのPlaceFlagMoveフラグ;

CharacterIDない場合このタグは何をするか?

• 指定したDepthにある既にplace済の

Objectの属性変更

• CharacterIDあると同じDepthに二重placeになってしまうので

どういうこと? 59

DisplayList

Depth=2

Depth=1

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(0,0)

Depth=3

どういうこと? 60

Depthで一意にオブジェクトが決まらない

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(50, 50)

DisplayList

Depth=2

Depth=1

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(0,0)

Depth=3

どういうこと? 61

DisplayList

Depth=2

Depth=1

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(0,0)

Depth=3

どういうこと? 62

PlaceFlagMove=1にして設置済みのObjectの修正をする

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=1 (x,y)=(50, 50)

DisplayList

Depth=2

Depth=1

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(0,0)

Depth=3

どういうこと? 63

CharacterIDを持たせることで違うObjectへの入れ替えも

RemoveObject2をタグ使わないでもできる

PlaceObject2

CharacterID=3 Depth= 1

PlaceFlagMove=1 (x,y)=(50, 50)

DisplayList

Depth=2

Depth=1

PlaceObject2

CharacterID=1 Depth= 1

PlaceFlagMove=0 (x,y)=(0,0)

Depth=3

エレメントの対応

エレメント: ベース画像の上に乗せる画像パーツ ・差分だけトリミングした画像を重ねて別画像を表現

64

・表情の変化や小規模な装飾を最小の画像容量で実現

顔の部分以外は共通 差分だけトリミング

パーツの重ね合わせで表現

エレメントの対応

65

・画像の挿入(置換でない) ⇒

DefintBitsLossless2 DefineShape PlaceObject

Tag Tag Tag Tag Tag Tag

DefintBitsLossless2 DefineShape PlaceObject

▪ DefineBitsLossless2, DefineShape,PlaceObejct2タグを新規に作ってSWF内にタグ挿入する必要がある

▪ Depthを表示順に合わせて決める 重複しないように注意

エレメントの対応 66

Header Tag Tag Tag Tag Tag Tag Tag Tag

Tag Tag

DefineBitsLossless2 DefineShape

Header Tag … Tag Tag Tag

Tag Tag

RemoveObject2 PlaceObject2

Tag Tag

RemoveObject2 PlaceObject2

▮キャラクターMCのDefineSpriteより前に画像定義を挿入 ▮表示順に注意してDepthの設定をしたPlaceObject2を キャラクターMCの適当なフレームに挿入 (必要に応じてRemoveObject2タグも)

キャラクターMCの DefineSpriteタグ

DefineSpriteタグ(Tag type=39) 67

タグ

a a

: DoAction

: ShowFrame

: PlaceObject2

: RemoveObject2

・タグの塊を内部に持つ ⇒置換の際にこのタグ内タグを見る必要もある ・Control系のタグのみ(Definition系は丌可) ⇒配置するキャラクタはこのタグより前で定義

Header

FrameCount

ControlTags

tag

tag

tag

SpriteID

END

1 2 3 4 5 6 7 8

1 2 3 4 5 6 7 8

▮ムービークリップを定義する

tag

アニメーションの対応

こういうMCをつくって埋め込む (つくるMCの数は任意個)

68

1 5 10

a a

・必要な画像のDefineBitsLossless2, DefineShapeタグを登録 ・DefineSpriteタグでMC定義、その中に

1. 表示する画像のDefineShapeタグを設置するPlaceObject2タグ 2. 各画像表示時間の調整用にフレーム稼ぎのShowFrameタグ 3. くりかえ(す|さない)などの制御用スクリプトのDoActionタグ

・DefineSpriteで定義したMCを名前付きでPlaceObject2タグで設置

アニメーションの対応 69

Header Tag Tag Tag Tag Tag Tag Tag Tag

Tag Tag

DefineBitsLossless2 DefineShape

DefineSprite

Header Tag … Tag Tag Tag

Tag Tag

RemoveObject2 PlaceObject2

Tag Tag

RemoveObject2 PlaceObject2

▮キャラクターMCのDefineSpriteより前に画像定義を挿入 ▮表示順に注意してDepthの設定をしたPlaceObject2を キャラクターMCの適当なフレームに挿入して アニメーションをDefineしたSpriteをPlaceする

キャラクターMCの DefineSpriteタグ

Tag

2. それぞれ独立したDepth空間を持っています

DefineSpriteについて 70

3 2 1

Depth: 8 Shape Sprite Text

Shape

3 2 1

Depth:4 Text Shape Shape Text

Display List (Main)

Display List (Sprite)

1. DefinSprite内におけるタグはControlTagだけなので 入れ子になったムービークリップでもDefineSprite タグは入れ子にはなりません(子は親よりも前に定義する)

Header Tag Tag Tag Tag

MC1

MC2

DefineSprite(MC2) DefineSprite(MC1)

Tag

サウンドの対応

台詞を声付きでしゃべるキャラクターもいる ⇒音声ファイル(MP3, MMF(SMAF))の埋め込み 携帯用の音声ファイル ⇒動的生成だと直接挿入可能

71

1 5 10

a

・こういうムービークリップをつくる - いきなり再生されないようにstop(); - 音声データの定義と配置(DefineSound, StartSound) - 再生時間に応じてフレーム数を伸ばす

・PlaceObject2で名前付き(例. “se0”)で配置 ・tellTarget(“se0”){gotoAndPlay(2);}で再生開始

・普通に再生する分にはSoundInfo情報必要ない ⇒SoundInfoフィールドは”0x00” でOK (PC向けで多重再生回避の場合は”0x10”でもいいかも)

StartSoundタグ(Tag type=15)

▋ DefineSoundした音声をSoundIDで識別して再生

音声の定義と再生:[DefineSound]-[StartSound]の組

72

タグヘッダ

SoundID

SoundInfo

【StartSound】

以下あるか等

InPoint

OutPoint

LoopCount

EnvPoints Envelope Records

開始ポイント指定

繰り返し回数

エンベロープ点と その内容

停止ポイント指定

以下あるかの他、SyncStop, SyncNoMultipleの設定

DefineSoundタグ(Tag type=14)

▋ 音声の定義 • MP3の場合はサンプル数算出などに要MP3バイナリの構造解析 • 携帯用フォーマットは仕様書外?置換には計算いらないので楽

73

タグヘッダ

SoundID

フォーマット(0~6, 11) SoundFormat

SoundRate

SoundSize

SoundType

SoundSampleCount

SoundData

【DefineSound】

サンプリングレート (0=5.5kHz, 1=11kHz, 2=22kHz, 3=44KHz)

バイナリデータ

8bitか16bitか ステレオかモノラルか

SWF内での識別用ID

サンプル数 1グラニュール=576サンプル

MP3: 2, MMF(SMAF): 15

MMF(SMAF): 0

MMF(SMAF): 0

MMF(SMAF): 0

MMF(SMAF): 0

MMF(SMAF): ファイルバイナリ

と、まあ

『まめフラスコ』ではこんな感じのことをやっています

74

75

FlashLite以外での動的SWF生成

ActionScript3でやりたいんだけど…

76

⇒変数まとめてバイナリで渡そう

DefineBinaryDataタグを使うよ

• VirtualMachineが一新(AVM2) • DoActionタグからDoABCタグになった • これまでの素朴な埋め込み難しい

キャラクターID Name:“Main_HogeZip”

DefineBinaryDataタグ(tag type=87)

77

このように埋め込んだバイナリを使う場合 あらかじめ埋め込んだダミーのバイナリを もつDefineBinaryDataタグ内のバイナリ 部分の置換だけで済む

タグヘッダ

キャラクターID

バイナリデータ (ここだけ置換)

【DefineBinary】

[Embed(source=“hoge.zip”, mimeType=“application/octet-stream”)] static private var HogeZip: Class;

var ba:ByteArray = new HogeZip as ByteArray;

▋ 任意のバイナリの埋め込みができる

【SymbolClass】 【DoABC】

“Main_HogeZip”

ActionScript3なので…

78

ActionScript3 ⇒ まともな文法、まともな速度

前処理なしの設定ファイルをそのまま埋め込んで ASでパースも可

バイナリ ⇒ 何でもあり

• (SWFバイナリ処理をAirでやる場合は特に) データバイナリとしてAMF形式も可

• Zipで複数ファイル埋め込むのもありです

• MessagePackとか?

ActionScript3なので…

「プレイヤー同梱型のデータ」 ユーザ主導での配布・更新・課金

79

lite制限ないのにわざわざ単一ファイル化?

• 外部ファイル読み込みの簡略化(非同期は面倒)

• SWF⇒Air化 Android/iPhone用への展開

• 電子書籍(+α) • ゲームツクール • ビジュアルノベルランタイム

動的SWF生成のほかのかたの例

80

▮text to flash(txt2swf)

テキストファイルをFlashに変換 青空文庫を携帯で読む「携帯Flashリーディングス」さんでも使われています http://www.kaseijin.biz/pc.htm

▮VNC2SWF

画面録画ユーティリティ VNCの画面を録画、音声や編集も対応、オープンソース(GPL) http://www.unixuser.org/~euske/vnc2swf/index-j.html

▮Fiora au用ケータイメニュー画面を作成 GUIで楽々作成 携帯電話のユーザによるカスタマイズ http://auicon.freeownhost.com/pc/tools/fiora/

• FlashLiteの制限を超えていろいろできるよ

• 1バイトでも削りたいとき試せることが増えるよ

• ちょっと変わったサービスも作れるかも

• いろいろ勉強になるね (compiler, MP3/Zip format, …)

• Flashに詳しくない人でもFlashPlayerの普及性を享受

していろいろ作れるね

• 楽しいね!

おわりに

動的にSWFファイルを作ると

81

ご清聴ありがとうございました

おしまい

82

参考・引用文献など

• “ばぐとら研究所”(Chameleon Ponapalt さま)

http://ssp.shillest.net/

83

• “SWF File Format Specification Version 10”(Adobe Systems Inc.さま)

http://www.adobe.com/devnet/swf.html 『SWF Technology Center』内

• “「.さくら」”(駅長 さま)

http://www.nanican.net/dot-sakura/ 『.さくらステーション』内

• “from ”BaMHA” ”(サトウ M さま) http://sgmh.sakura.ne.jp/tcg/ 『TCG-檻の少女』内

• “SWFバイナリ編集のススメ(よや さま)

http://labs.gree.jp/blog/2010/08/631/ 他『GREE Engineers’ Blog』内

• “ming/JPEG”(939 さま) http://auicon.freeownhost.com/pc/index.php 『auicon by 939』内