actionscriptを使わないflash勉強会 #1(前日版)
TRANSCRIPT
クライアントサイドにおける
動的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』内