2012/09/08(土) [n年前の日記]
#1 [as3][flash][actionscript][cg_tools] FlashDevelopでFXGを使う
全然知らなかったのだけど、Adobe は FXG というベクター画像フォーマットを打ち出していたらしい。Flex あたりで利用することを想定してたのだろうか。一応、Illustrator 等、Adobe各製品から出力することができるらしい。
FlashDevelop上で svg を Embed してたら、コンパイラが「svg なんかより fxg のほうがオススメだよ!」とわざわざ警告を出していて。そこでようやく、そんな画像フォーマットがあることに気付いたわけで。
試しに FXG とやらも ActionScript3 で表示してみたい。と思ったものの、svg から fxg に変換するツールが全く見つからない…。
_flex4 - FXG Editor for Flex - Stack Overflow で、Inkscape から FXG として別名保存できる拡張を見かけた。
_svg2fxg.inx と _svg2fxg.xsl のページからそれぞれファイルを取得して、Inkscapeインストールフォルダ\share\extensions\ 以下にコピーしたら、別名保存時に "Flash XML Graphics (*.fxg)" という選択肢が選べるようになった。
これで FXG ファイルが出来たので、FlashDevelop を使って表示の実験。以下のページを参考に。
_FlashDevelop.org - View topic - How to embed vector images ?
_[Flex] グラフィックアセットの埋め込み | クラスメソッド開発ブログ
svg画像の場合は、ソース中でEmbedを記述して埋め込んでいたけれど。FXG の場合は、import で埋め込む(?)らしい。例えば、ソースと同じ階層に Hoge.fxg というファイルを置いたなら、import Hoge; とすればいい。package piyo.fuga 以下なら、import piyo.fuga.Hoge; になるのかな。たぶん。
呼び出す・使う時は、var spr:Sprite = new Hoge() as Sprite; みたいな感じ。
で。実際表示してみたのだけど。svgの時には表示されていたものが、fxgになったら表示されなかった。どうやら、Inkscape で無頓着に保存した FXG は、svg のコマンド?の一部しか対応していないっぽい。 _SpecFXGExport - Inkscape Wiki にも、Not supported の一覧が。
Inkscape 上で、グループ解除、オブジェクトをパスに変換、等をした上で、最適化svg として保存した後、その svgを開いた直後に fxg保存してみたり。…これなら一応それらしく表示された。
ただ、Inkscape では、保存した FXG を開き直すことができないようで。これでは一方通行、最終保存フォーマットだな…。なかなか厳しい。しかも、 _flex4 - FXG Editor for Flex - Stack Overflow では、Inkscape で保存した FXG を Flash CS 5.5 で読み込んだらクラッシュした、なんて話も。ますます厳しい。
FlashDevelop上で svg を Embed してたら、コンパイラが「svg なんかより fxg のほうがオススメだよ!」とわざわざ警告を出していて。そこでようやく、そんな画像フォーマットがあることに気付いたわけで。
試しに FXG とやらも ActionScript3 で表示してみたい。と思ったものの、svg から fxg に変換するツールが全く見つからない…。
_flex4 - FXG Editor for Flex - Stack Overflow で、Inkscape から FXG として別名保存できる拡張を見かけた。
_svg2fxg.inx と _svg2fxg.xsl のページからそれぞれファイルを取得して、Inkscapeインストールフォルダ\share\extensions\ 以下にコピーしたら、別名保存時に "Flash XML Graphics (*.fxg)" という選択肢が選べるようになった。
これで FXG ファイルが出来たので、FlashDevelop を使って表示の実験。以下のページを参考に。
_FlashDevelop.org - View topic - How to embed vector images ?
_[Flex] グラフィックアセットの埋め込み | クラスメソッド開発ブログ
svg画像の場合は、ソース中でEmbedを記述して埋め込んでいたけれど。FXG の場合は、import で埋め込む(?)らしい。例えば、ソースと同じ階層に Hoge.fxg というファイルを置いたなら、import Hoge; とすればいい。package piyo.fuga 以下なら、import piyo.fuga.Hoge; になるのかな。たぶん。
呼び出す・使う時は、var spr:Sprite = new Hoge() as Sprite; みたいな感じ。
で。実際表示してみたのだけど。svgの時には表示されていたものが、fxgになったら表示されなかった。どうやら、Inkscape で無頓着に保存した FXG は、svg のコマンド?の一部しか対応していないっぽい。 _SpecFXGExport - Inkscape Wiki にも、Not supported の一覧が。
Inkscape 上で、グループ解除、オブジェクトをパスに変換、等をした上で、最適化svg として保存した後、その svgを開いた直後に fxg保存してみたり。…これなら一応それらしく表示された。
ただ、Inkscape では、保存した FXG を開き直すことができないようで。これでは一方通行、最終保存フォーマットだな…。なかなか厳しい。しかも、 _flex4 - FXG Editor for Flex - Stack Overflow では、Inkscape で保存した FXG を Flash CS 5.5 で読み込んだらクラッシュした、なんて話も。ますます厳しい。
◎ Webサイト上でFXGを作れるサービスがあるらしい。 :
_FXG Editor Guide
_FXG Editor
_SVG Editor
FXG あるいは SVG を作成できる模様。と思ったが、FXG Editor で画像を作成して保存したら画像が真っ黒になってしまった。また、そもそもローカル保存できないような…。xml内容をウインドウに表示することができるから、それをコピペしてどうにか、という感じなのかなあ。
全然関係ないけど、ギャラリー内で上手く保存できなかったアイテムを削除できる機能が欲しいと思ったり。
_FXG Editor
_SVG Editor
FXG あるいは SVG を作成できる模様。と思ったが、FXG Editor で画像を作成して保存したら画像が真っ黒になってしまった。また、そもそもローカル保存できないような…。xml内容をウインドウに表示することができるから、それをコピペしてどうにか、という感じなのかなあ。
全然関係ないけど、ギャラリー内で上手く保存できなかったアイテムを削除できる機能が欲しいと思ったり。
[ ツッコむ ]
#2 [as3][flash][starling] Starling を使ったAIRアプリを作るための下準備をメモ
Windows7 x64 + FlashDevelop 4.0.4 + Flex 4.6.0 + AIR 3.3 で作業。
swcの追加は、もっと簡単な方法があったらしい。 _FlashDevelopの使い方 (15)SWC形式のライブラリをProjectパネルから簡単に指定する方法 - 独学ActionScript で説明されてた。
- 新規プロジェクト作成。AIR AS3 Projector を選択。名前に、任意のプロジェクト名を、パッケージに、com.hogefuga みたいな感じで入力。
- プロジェクトフォルダ\lib\ 以下に、starling.swc をコピー。
- プロジェクト設定 → コンパイラー設定 → SWC Libraries の右側のボタンを押して、lib\starling.swc を入力。
- プロジェクト → AIRアプリケーション設定 → Initial Window → 非ウインドウ表示プラットフォーム → レンダリングモード、を Direct に。これをしないと Starling では画面が表示されない。
- bat\SetupSDK.bat を開いて、set FLEX_SDK=〜 の行を自分の環境に合わせて修正。
- bat\CreateCertificate.bat を実行。右クリックして実行を選べば実行できる。
- ソースを書いて、プロジェクトをビルド(F8キー)。
- プロジェクトをテスト(F5キー)。
swcの追加は、もっと簡単な方法があったらしい。 _FlashDevelopの使い方 (15)SWC形式のライブラリをProjectパネルから簡単に指定する方法 - 独学ActionScript で説明されてた。
[ ツッコむ ]
#3 [as3][flash][starling] Starling使用中のウインドウをリサイズする際の処理でハマる
Windows7 x64 上で Starling を勉強中なのだけど。ウインドウサイズを変更した際に、表示内容もウインドウサイズに合わせて拡大縮小させようとしたものの、何度もサイズを変更してるうちにエラーが出て Flash Player が固まってしまう不具合が出てハマってしまったり。
ウインドウサイズ変更時は、Event.RESIZE でイベント発生させられるのだけど。もしかすると前のリサイズ処理がまだ終わってないうちに、次のイベントが発生して、マズイことになってるのかなと。しかしそれなら、まだ処理中だよ的フラグを用意すれば、そこそこ改善するはずで。しかし、相変わらずエラーが出る。改善できてるように見えない…。
変更したら必ず固まるわけではないのが困る。時々何かの拍子に発生するようで。Starling.current.viewPort = viewport; のあたりがおかしいのかなあ…。よくわからん…。
色々試したけど、どうにかエラーが出ない感じになったかもしれず。とりあえず、Main.as は下のようになった。
ハマってた時のソースから変えた部分をメモ。
以下、よくわかってないけど。
ウインドウサイズ変更時は、Event.RESIZE でイベント発生させられるのだけど。もしかすると前のリサイズ処理がまだ終わってないうちに、次のイベントが発生して、マズイことになってるのかなと。しかしそれなら、まだ処理中だよ的フラグを用意すれば、そこそこ改善するはずで。しかし、相変わらずエラーが出る。改善できてるように見えない…。
変更したら必ず固まるわけではないのが困る。時々何かの拍子に発生するようで。Starling.current.viewPort = viewport; のあたりがおかしいのかなあ…。よくわからん…。
色々試したけど、どうにかエラーが出ない感じになったかもしれず。とりあえず、Main.as は下のようになった。
package com.blawat2015 { import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.geom.Rectangle; import starling.core.Starling; [SWF(width="480",height="320",frameRate="60",backgroundColor="#000000")] /** * Starling + ウインドウサイズ変更のテスト */ public class Main extends Sprite { private var myStarling:Starling; private var resize_exec:Boolean = false; /** * コンストラクタ */ public function Main():void { // stage が既に存在しているなら即座に、 // stage が存在していないならステージ生成時に、初期化メソッドを呼ぶ。 if (stage) init() else addEventListener(Event.ADDED_TO_STAGE, init); } /** * 初期化処理 * @param e */ private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; stage.quality = StageQuality.BEST; // Starlingのインスタンスを生成 var viewport:Rectangle = new Rectangle(0, 0, _g.STGW, _g.STGH); myStarling = new Starling(MySprite, stage, viewport, null, "auto", "baseline"); myStarling.antiAliasing = 1; // アンチエイリアス設定 myStarling.showStats = true; // 状態表示有効化 myStarling.enableErrorChecking = true; // エラーチェック myStarling.start(); // 描画処理開始 // ウインドウリサイズ時の処理を設定 stage.addEventListener(Event.RESIZE, onResize); } /** * ウインドウリサイズ時に呼ばれる処理 * @param e */ private function onResize(e:Event):void { // 処理中にイベントが再発生するとマズいので、フラグでチェック if (resize_exec) return; resize_exec = true; var v:Rectangle, sw:int, sh:int; myStarling.stop(); // 念のために描画を停止しておく do { sw = stage.stageWidth; sh = stage.stageHeight; v = new Rectangle(0, 0, sw, sh); // 縦横拡大率を求める _g.wdw_scaleX = sw / _g.STGW; _g.wdw_scaleY = sh / _g.STGH; if (_g.wdw_scaleX > _g.wdw_scaleY) { // 横に引き延ばし過ぎ var w:int = int(_g.STGW * _g.wdw_scaleY); if (v.width > w) v.width = w; v.x = int((sw - v.width) / 2) & 0xfff8; _g.wdw_scaleX = _g.wdw_scaleY; } else if (_g.wdw_scaleX < _g.wdw_scaleY) { // 縦に引き延ばし過ぎ var h:int = int(_g.STGH * _g.wdw_scaleX); if (v.height > h) v.height = h; v.y = int((sh - v.height) / 2) & 0xfff8; _g.wdw_scaleY = _g.wdw_scaleX; } // 処理中にウインドウサイズが変更されてたら算出し直し } while (sw != stage.stageWidth || sh != stage.stageHeight); myStarling.viewPort = v; myStarling.stage.stageWidth = _g.STGW; myStarling.stage.stageHeight = _g.STGH; myStarling.start(); // 描画再開 _g.wdw_w = sw; _g.wdw_h = sh; resize_exec = false; } } }ちなみに、main.as とは別に、MySprite.as、_g.as が用意してある。
ハマってた時のソースから変えた部分をメモ。
- new Starling() を呼ぶ際に与えるパラメータを、巷のサンプルでよく見かける記述から少し変えてみた。巷では、new Starling(MySprite, stage, viewport); になってることが多い印象。
- リサイズ時に、Starling.current.viewPort = 〜 ではなくて、既に記憶していた Starling のインスタンス変数を使うようにした。
- 短い時間内に連続してリサイズ処理が呼ばれる場面があるのかと思い、一定時間が経過してからリサイズ処理をするようにしてみたけど改善されず。なので、そういう複雑(?)なことは全部止めて、リサイズイベントが発生したら、すぐにさっさと処理するようにした。
- リサイズ時に、Starling.stop()、start() を呼ぶようにした。しかしコレをしても改善しなかったので関係ないかも。
- viewPort を弄る直前まで、処理途中でウインドウサイズが変更されてる可能性を意識するようにした。もし、途中でウインドウサイズが変わってたら、do - while の部分で処理をし直す。
以下、よくわかってないけど。
- viewPort に与えるのは、実際のウインドウサイズ内で、どこからどこまでを表示範囲にするか、という値。Rectangle の x,y が、領域の左上。width, height が、領域の縦横幅、なのかな?
- Starling.stage.stagWidth, stageHeight に与えるのは、表示範囲を、何x何ドットの領域として扱うか、という値。
- 480x320 のゲーム(?)画面を、1920x1080のウインドウサイズ内に表示しようと思ったら…。
- viewPort には x,y,w,h=(0,0,1920,1080) を与えて、stageWidth,stageHeight には (480,320) を与える。
- これだと縦横比が妙なことになる・横に引き延ばされた見栄えになる。
- 縦横比を合わせて、表示範囲をセンタリングしたいなら、viewPort に、x,y,w,h=(150,0,1620,1080) を与える。
[ ツッコむ ]
以上、1 日分です。