[AS]FlashBuilder4.7(Beta)で「VerifyError: Error #1107: ABC データは破損しているため、境界外の読み取りが試行されました。」と出たときの対処法


****2012.10.11追記*****
FlashBuilder4.7Beta2では下記のエラーはでなくなった模様
ただ自分のボタンシンボルを含んだサンプルをパブリッシュしたら、レイアウトが盛大に崩壊したりしていて、なんか挙動がとても怪しい気がする・・・
(具体的にどういうときに崩れるかはちゃんと検証してない)
****************************

FlashBuilder4.7では新しいASコンパイラが搭載されているので、過去に作ったプロジェクトを書き出そうとエラーがでることがあります。

今日遭遇したのはこれ

その1:VerifyError: Error #1107: ABC データは破損しているため、境界外の読み取りが試行されました。

その2:Error #2022: Class [※hogehoge] must inherit from DisplayObject to link to a symbol.

[※hogehoge]の内容はいろいろ変わる

これは、FlashIDE上で作ったアセット的なSWCファイルからリンケージしたボタンシンボル(SimpleButton)を読み込もうとすると発生するエラーみたい。
リンケージしたムービークリップシンボルの中にボタンシンボルが含まれててもダメ。

リンケージしたボタンシンボルを呼ぼうとすると、上記:その1のエラーがでて
ボタンシンボルを含むリンケージしたムービークリップシンボルを呼ぼうとすると、その2のエラーがでました。

で、今再現確認してみたところ、リンケージしたムービークリップシンボルの中にボタンシンボルが含まれてる場合はエラーでなくなった・・・なんでだろう。
でも、そのムービークリップを表示してみると、含まれてるはずのボタンシンボルがひとつも表示されないのでやっぱり何かおかしいみたい。

とりあえずFlashBuilder4.7で使うアセットSWCにはボタンシンボルは使わないほうがいいみたい。

[iPhone][Alternativa3D][AIR]AIR for iOSでシンプルな3Dゲームをリリースしました。

メモ記事を書いてましたが先週やっとiPhoneアプリとしてリリースしました。

Live with the Wind.
support site
itunesStore

初めてFlash:Air for iOS(AIR3.3SDK)で作ってみたよ。
3DエンジンにはAlternativa3D(8.17.0)を使用したよ。

もろもろ苦戦したことは以前公開したStage3D勉強会#2の資料に書いたので興味ある方は読んでみてください。


■実装以外でのゲーム性について
▼気持ちよさの工夫
BGMのBPMに連動するような動きを意識
→風を連続で取ったときの効果音がBPMと連動するようにスピードを調整
→風車の首を降り始めは曲調が変わるタイミング
→あと風車が首を振るときのスピードもBPMと連動するような

▼飽きさせない工夫
上昇気流だけを取り続けて飛ばれるとゲームオーバーになりにくいが緊張感なくなりゲームが単調になる
追い風も取らせて緊張感のあるゲーム展開にしたい
→上昇気流だけを取りつづけた場合は無理ゲーになるような設定に。
 (風車の背がどんどん伸びていく)
→2種類のコンボ要素の追加
 (コンボを続けると風車の背が伸びにくくなるようにしている)
※「上昇気流を取る→風車がのびる」という部分がルール的には判りにくくなってしまったのでヒントの項目に記載したけど理解できてない人も多いかも。。

▼操作性について
iPhoneアプリというと傾きセンサーだけど今回は無しで。
プレイヤーが学習してやりこみ性あるゲームにしたかった。
傾きセンサーでは細かいコントロールができないので運要素が増えてしまう
個人的に思うようにコントロールできないのは嫌い、というのが一番の理由
あと電車でプレイしてる姿も少し恥かしくなるしね。


8月中は無料で9月から170円になりますので是非試してみてくださいまし。

※Flash製なので簡単にWEBおためしプレイ版も用意できますよ。
>FlashPlayer11.0
(音鳴ります)

[AIR]FlashCS5で作ったAIR用flaファイルをCS6で編集しようとするときの罠

ちょっとハマったのでメモしときます。
Windows版での話です。(mac版は持ってないのでわかりません。。)


FlashCS5で作ったAIR用(AIR2.0)flaファイルをFlashCS6で開いてムービープレビューしようとするとどうなるか。

何もおきません。
エラーもでません。
SWFのウィンドウも表示されません。
もう一度いいます、何もおきません。
パソコン再起動してもムービープレビューできません。


仕方ないのでCS6では保存せずにCS5で開いてムービープレビューしてみます。

何もおきません。
エラーもでません。
SWFのウィンドウも表示されません。
もう一度いいます、何もおきません。

なにこれ、ばかなの、死ぬの、という言葉が頭を巡りました。


んで結論からいうと[ファイル名-app.xml]に不具合が起きていました。


通常app.xmlはIDE側で各パラメーターを設定すればそれがapp.xmlに反映されるものなので中をみなくてもいいものだったりします。

まずはCS5で作ったflaファイルをCS6で開こうとすると

こんなアラートがでて、ターゲットがAIR3.2 for Desktopに変更されます。

でそれに伴いapp.xmlの2行目のairsdkのバージョンの項目も3.2に修正されます。

<!-- hoge-app.xmlの2行目 -->
<application xmlns="http://ns.adobe.com/air/application/3.2">

親切ですね!

でもムービープレビューできません。
なぜでしょうか?

それはAIR2.0からAIR2.5へ変わる際に1箇所app.xmlの仕様が変更になったからです。
具体的にはapp.xmlの4行目。

<!-- AIR2.0以下での4行目 -->
<version>1.0</version>
<!-- AIR2.5以上での4行目 -->
<versionNumber>1.0</versionNumber>

varsion要素がversionNumber要素に変わったようです。
ここの変更はFlashCS6は自動で直してくれません。

不親切ですね!

というわけでxmlのここの部分を修正してあげるとFlashCS6でムービープレビューができるようになります。


さてもう一点、
CS6で開いたflaファイルを保存せずに閉じて、CS5で開き直したらムービープレビューできなくなってしまう件。

これもxml2行目の部分が原因です。
先ほどCS6で開いた時点で、sdkバージョンの項目が3.2に書き換えられました。
でもCS5で開きなおしたときにはとくに何のアラートも表示されません。
パブリッシュ設定上はAIR2.0設定になってるんですが、app.xmlをみてみると2行目は3.2のままです。
どうやらCS5では自動で修正してくれないようです。

不親切ですね!

というわけで一度CS6で開いてしまうとxml2行目が書き換わってしまうので手動で修正してあげましょう。
あと4行目のversion,versionNumbber要素の部分も当然CS5は自動で書き直してはくれないのでversionに戻しておきましょう。


まとめ。
中途半端な親切はかえって迷惑。

[JSFL]座標の小数点を丸めるJSFL使用時の注意(Windows FlashCS4,CS5で確認)

ステージ上のオブジェクトの座標を整数に丸めてくれる便利JSFLに罠があることに気づきました。
CS5で気づいて、CS4でも同じことになったから既知の現象でしょう。

丸めるJSFLはいろんな方が公開してくれてるのでボクもどこかで拾ったものを使ってます。
↓こんなの

var doc = fl.getDocumentDOM();
if (doc.selection.length) {
for (var i = 0 ; i < doc.selection.length ; i++){ var mat = doc.selection[i].matrix; mat.tx = Math.round(mat.tx); mat.ty = Math.round(mat.ty); doc.selection[i].matrix = mat; } } [/sourcecode] 選択したオブジェクトを一括でバーンと変換してくれて便利なんですが、保存時に結果を変換後の座標を保持してくれないことがあるようだということに気づき、なんとなく原因と対策っぽいこともわかったのでメモしときます。


まず、座標を保持しない再現手順を書きます。
(うちでの再現率:100%)

■手順(準備編)

  • 1.新規flaファイルを作成
  • 2.何でもいいから四角いシェイプを書いてMC化(シンボル1とする)
  • 3.シンボル1をさらにMC化(シンボル2とする)
  • 4.シンボル2の中に入り、シンボル1のx座標を0.5にする(プロパティパネルから数値変更)
  • 5.保存して、ファイルを閉じる。
  • 6.再度ファイルを開き、シンボル2の中のシンボル1の座標を確認するとx座標は0.5となっている。

→ここまでは何の問題もない

■手順(不具合発生編)

  • 7.シンボル1を選択した状態で上記JSFLを実行する。
  • 8.プロパティパネル上では0.5が1となっているはず。
  • 9.ファイルを上書き保存して閉じる。
  • 10.ファイルを開いて、シンボル2の中のシンボル1の座標を確認するとx座標は0.5となっている。

→なにこれ、ばかなの、しぬの


ちなみにJSFLを使わずに手動でプロパティパネルの数値を0.5→1に変更した場合は保存は反映されます。
(当たり前か)

では何が問題か。
ここからは推測ですが、上記JSFLでの結果ではflaファイル的には「変更扱いにされていない」っぽいようです。
ためしに上記手順8まで実行した状態でファイルを保存するまえにシンボル2の中のタイムラインのレイヤーをひとつふやしてから保存して開き直してみると、こんどはちゃんとシンボル1座標変更が反映されているのが確認できます。

ここで注意が必要なのは、シンボル2の中のタイムラインをいじったということ。

シンボル2のタイムラインではなく、メインタイムラインのレイヤーをひとつふやしてもシンボル1の座標変更は反映されません。
つまりはFlashはMC単位で変更があったかなかったかを判断して、状態を保存するかしないかを決めてるっぽいので関係ないタイムラインに変更を加えても意味がない、ということになりそうです。


というわけで、対策
確実に「MCに変更を加えたぞ」と判らせてあげるために、上記JSFLを改造。

var doc = fl.getDocumentDOM();
if (doc.selection.length) {
for (var i = 0 ; i < doc.selection.length ; i++){ var mat = doc.selection[i].matrix; mat.tx = Math.round(mat.tx); mat.ty = Math.round(mat.ty); doc.selection[i].matrix = mat; } } //追加:レイヤーを追加して、追加したレイヤーを消す doc.getTimeline().addNewLayer(); doc.getTimeline().deleteLayer(); [/sourcecode] 最後に2行追加しただけです。 レイヤーを追加してすぐにその追加したレイヤーを削除する。 結果的には何の変化もない意味のない処理ですが、これで「MCに変更を加えたぞ」とflaに判らせてあげることができるようになります。 このJSFLを用いて上記手順を実行すると小数点丸めは確実に保存時に反映されるようなりました。 かなり力技な感じですが、もっとマシな方法がありました教えてくださいませ。 (果たしてCS5.5では直ってるのか?・・・まぁ直ってないだろうな。。)

[AS]AS3での、TextField.htmlTextでつかえる、HTML,CSSのまとめ

以前作ったもの。
ネットで検索できるようにメモ。

[AS][iPhone]FlashBuilder4.5のActionScriptモバイルプロジェクトで横向き固定の設定をした場合のステージサイズを正しく取得する方法

前の記事の続き、
FlashBuilder4.5のActionScriptモバイルプロジェクトでの設定のお話。

まず横向き固定にする方向は、hoge-app.xmlに

<!-- hoge-app.xml内のinitialWindow要素に指定 -->
<aspectRatio>landscape</aspectRatio> 

を設定するだけでOK。
これでデバッグプレビューすると確かに横向きでプレビューされる。
が、stage.stageWidthは320、stage.stageHeightは480と変更されていない。
(ちなみにFlexモバイルプロジェクトの場合はstage.stageWidthは480、stage.stageHeightは320となり問題ないようす)

ではどうしたらいいか、
結論としては、ドキュメントクラスのコンストラクタに以下の一行を追加
stage.setAspectRatio(StageAspectRatio.PORTRAIT);

//前提で、hoge-app.xmlに<aspectRatio>landscape</aspectRatio>と設定
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
trace(stage.stageWidth, stage.stageHeight); //出力:320,480
stage.setAspectRatio(StageAspectRatio.PORTRAIT);
trace(stage.stageWidth, stage.stageHeight); //出力:480,320

解せないのが、なぜPORTRAITなのか。
通常はPORTRAITは縦、LANDSCAPEは横をあらわすので、stage.setAspectRatio(StageAspectRatio.LANDSCAPE);と設定すればいいと思ったのだけど、これだとstage.stageWidthは320、stage.stageHeightは480のままとなった。

//前提で、hoge-app.xmlに<aspectRatio>landscape</aspectRatio>と設定
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
trace(stage.stageWidth, stage.stageHeight); //出力:320,480
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
trace(stage.stageWidth, stage.stageHeight); //出力:320,480

解せぬ。


※2011.8.15追記
上記設定だと実機転送した際に横方向にはならない様子。。。
やはりsetAspectRatio()にはStageAspectRatio.LANDSCAPEを設定しないと横向き固定にはなりませんでした。
上に書いたLANDSCAPE設定での懸念されるステージサイズは、
trace(stage.stageWidth, stage.stageHeight); //出力:320,480
となっているようで実機起動上では特に問題なさげ。
ステージサイズがちゃんと取れないのはデバッグプレビューだけでのバグってことなのか!?

※2011.8.18追記
コメント欄にて教えていただきました。
stage.setOrientation(StageOrientation.DEFAULT)を設定することで想定したstageサイズを取得することができました。

//前提で、hoge-app.xmlに<aspectRatio>landscape</aspectRatio>と設定
stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
trace(stage.stageWidth, stage.stageHeight); //出力:320,480
stage.setAspectRatio(StageAspectRatio.LANDSCAPE);
stage.setOrientation(StageOrientation.DEFAULT);
trace(stage.stageWidth, stage.stageHeight); //出力:480,320

[AS][iPhone]FlashBuilder4.5のActionSclriptモバイルプロジェクトにて、iOSでプレビューした際のステージサイズが正常に取れない場合

だいぶはまってネットに情報が見当たらなかったのでメモ。

FlashBuilder4.5でiPhone、Androind等のアプリを作るため、以下2つのプロジェクトが用意されました。

  1. Flexモバイルプロジェクト
  2. ActionScriptモバイルプロジェクト

1.はMXMLベースのプロジェクトで2はASだけで作れるプロジェクト。
ボクはMXMLはさっぱりなのでASだけで作れる2.を選択。
普通のFlashコンテンツを作ると同様にドキュメントクラスからゴリゴリ書いていけばOKですが、
iOS用の書き出しをした際にステージサイズの参照値おかしなことになりました。

こちらの想定は、シミュレートデバイスが、iPhone3GSなら320 × 480、
iPhone4設定なら、640 × 960となってほしいところですが、
stage.stageWidth,stage.stageHeightのtrace結果は常に、500, 375

なんぞこれ、と思えどステージサイズの設定する箇所は見当たらず。
ためしにapp.xmlのwidthとheightに直接値(320 480)を入れてみるも変化無し。
さらにドキュメントクラスにSWFのembedタグを書いてみるも変化無し。


FlashBuilderのHelpを観てみるとこんなページに行き着きました。
http://www.randytroppmann.com/2011/04/12/pure-as3-workflow-with-flex-builder-4-5/

そこに書かれていた見慣れぬ1行を追加してみると。。。

stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;

これを入れることでstage.stageWidth,stageHeightが想定通りの値となりました。
(シミュレートデバイスを変えることにより値も変化する)
とりあえず、よくわからんけど、上記一行は必須らしい。


P.S.
Retina対応もできるらしいけど、3G/3GSとRetinaの混合設定がよくわからん。。
highを書くだけで、Objective-Cみたいに自動でいい感じに変換してくれるのか、それとも2種類の画角を分けて作らないのいけないのか。。
Retinaの実機がないから検証できんのよね。。

[AS]ProgressionのPreloaderで”「Error #2044: ハンドルされていない ioError : text=Error #2036: 読み込みが未完了です。 URL: index.swf?”となってしまう場合の対処方法

ProgressionでPreloader.asからindex.swfを読み込むときにこんなエラーダイアログに悩まされてました。

どういうときにこのエラーになるかというと、Preloader.swfがindex.swfの読みこみが終わらないうちに、ブラウザを閉じてしまうとこうなります。
index.swfが重い場合、「ローディング長いからもう観なくていいや」ってブラウザ落とすと上記ダイアログで固まるんですね。
最高にうざい状態です。

で、エラーとしては、IOErrorってわかってるので、そこのエラー処理を書いてあげればいいんですけど、読み込みの処理はPreloader.asの親クラスに書いてあるので、どのオブジェクトに対して、IOErrorのハンドリングをすればいいのかわからなかったのですが、ついに重い腰をあげて親クラスの中身を覗いてみたら、5分で解決したというオチです。

結論としては、こんな感じ。

//Preloader.asの atReady()の中に一行追加
override protected function atReady():void{
//↓これを追加
this.addEventListener(IOErrorEvent.IO_ERROR, function():void { trace("エラー") } );
}

Preloader.asのatReady()の中で、thisに対してIOErrorのハンドリングを書けばOKです。

なぜ、thisに書くかといえば、Preloader.asの親クラス、CastPreloader.asの中にこの一行があるので。

_loader.contentLoaderInfo.addEventListener( IOErrorEvent.IO_ERROR, super.dispatchEvent );
//_loaderはindex.swfを読むためのもの

リスナー関数でsuper.dispatchEventを飛ばしてるから、Preloader.asのthisでイベントを取れるようです。

ちなみに、CastPreloader.as内の_loaderは、Preloader.asからはcontentLoaderInfoで参照が取れるので、Preloader.as内で、

//thisの代わりにcontentLoaderInfoでイベントをハンドリング
contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, function():void { trace("エラー") } );

という感じで書いてみると、一応traceは出力されるんですけども、traceの前に最初のエラーが表示されてしまい、まったく意味がないことになりました。
なので、contentLoaderInfoではなく、素直にthisでIOErrorEventをハンドリングすればOK。

[AS]SWFSizeを使うとIE6でフリーズする場合はDTD宣言に注意する

はまったのでメモメモ。

FlashをHTMLでの領域を指定できる便利ライブラリSWFSize。
Progressionにも採用されてて単体で使うケースがあんまりなかったのだけど、単体で使ったらIE6だけでエラーになった。
具体的には最低サイズ以下(resizeが機能したとき)になるとブラウザが固まる。

なんだこりゃとググってみると開発者のHIGEさんからのコメントが。

さらにググるとボクのケースでの原因と一致する記事を発見。
IEでonresizeの操作がうまくいかない – Miuran Business Systems

具体的にはDTDがonresizeに対応していなかったということ。

<!--最初に書いてた宣言-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<!--修正した宣言-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!--"http://www.w3.org/TR/html4/loose.dtd"を削除-->

普段DOCTYPE宣言とか意味もよくわからず呪文のように書いてる(正確にはコピペ…)からこういうところよくわからんです。。

[AS]fl.swcを使った際にちょっとはまったこと

ちょっとはまったので検索用のメモ

FlashIDEを使わずにFlexSDK(FlashDevelop)で製作中に、Flashのコンポーネント(具体的にはComboBox)が使いたいと。
FlashDevelopにはコンポーネントのライブラリが入ってない。
どっかにないかなと探すとfl.swcってやつが見つかった。

EVOLVE | Downloads

DLして、プロジェクトにライブラリパスを通すとコンポーネント系のコード補完がでるようになってインスタンス化することもできるようになった。

がしかし、addChidすると以下のようなエラーがでる。

TypeError: Error #2007: パラメーター child は null 以外でなければなりません。
at flash.display::DisplayObjectContainer/addChildAt()
at fl.controls::BaseButton/drawBackground()
at fl.controls::BaseButton/draw()
at fl.core::UIComponent/drawNow()
at fl.controls::ComboBox/drawLayout()[D:\DEVELOP\test_lib\fl\controls\ComboBox.as:1500]
at fl.controls::ComboBox/draw()[D:\DEVELOP\test_lib\fl\controls\ComboBox.as:1421]
at fl.core::UIComponent/callLaterDispatcher()

たぶんコードはあるけど、アセット的なグラフィックデータが用意されてないんじゃないかなぁ、と。
ランタイムエラーかつ、妙な時間差で発生するので、何が悪いかわからなくてちょっとはまってしまった。
対策としては、FlashIDEからあらかじめComboBoxクラスを埋め込みアセットクラスでswcとかにして書き出しておき、それを使えばaddChildしてもエラーにならずに使うことができるよ、と。

あらかじめ、コンポーネント一式を含んだオレオレswcを用意しておいてもいいかもね。