2008年2月アーカイブ

JavaScript で ByteArrayクラスを作ってみました。
まだ完全に実装してるわけではないけどもとりあえずアップしとくことに。

zip圧縮、解凍とエンコードの変換は、それぞれ以下のライブラリを使わしてもらってます。

[ecl.js]エンコード変換
URL : http://nurucom-archives.hp.infoseek.co.jp/digital/

[deflate.js]zip圧縮
URL : http://www.onicos.com/staff/iz/amuse/javascript/expert/

[inflate.js]zip解凍
URL : http://www.onicos.com/staff/iz/amuse/javascript/expert/

メソッドは
"readObject()" と "writeObject()" と "writeMultiByte()" がまだ実装してません。
"writeObject()" はほんとどうやって実装しよう・・・って感じです。
AS3版とは仕様を変更して、オブジェクトのプロパティ抜いてStringに変換とかすれば楽なんだけども。

あと、まだ配列アクセス([])できません。致命的ですが。

サンプルページとソースのダウンロードはこちら。
サンプル
ByteArray.js
ソースのダウンロード

ちゃんと動くのはFirefoxだけかも。
Safariはマルチバイトエンコードがうまくいってないっぽい。
他のブラウザは__defineGetter__が対応してないと無理だと思う。

実際このスクリプトが使える代物かというと、100%使えないと思う。

とりあえず今回実装してみて、JavaScriptでバイナリデータを読み込むことと
浮動小数点数(FloatとDouble)について、少し理解できたくらい。

でも浮動小数点数のところは、かなり力技なので、
もっと綺麗に書く方法知ってる方は是非とも教えてください。

それから、JavaScriptでクラスを書く方法も"これが正攻法"ってのが
結局わからなかったので、これも知ってる方、教えていただけると幸いです。

なんか今日はずいぶん人任せなエントリーになってしまった。

以前書いた「画像をロードしたMC 上に attachMovie」という記事に
助言をいただきまして、ちょっと試してみたので掲載しておきます。

読み込み先の"sub.swf"には「imageMC」というムービークリップが配置されてます。
var mc:MovieClip = this.createEmptyMovieClip("loadSWF",10);
var loader:MovieClipLoader = new MovieClipLoader();
listener = { onLoadComplete:function(){
    trace(mc.imageMC);                      // output 1
    mc.onEnterFrame=function(){
      trace("onEnterFrame : "+mc.imageMC);  // output 2
      delete this.onEnterFrame;
    }}, 
    onLoadInit:function(){
      trace("onLoadInit : "+mc.imageMC);    // output 3
    }};
loader.addListener( listener );
loader.loadClip( "sub.swf" , mc );
出力結果
undefined
onEnterFrame : _level0.loadSWF.imageMC
_level0.loadSWF
onLoadInit : _level0.loadSWF.imageMC
出力結果の1行目は "output 1" 、2行目は "output 2"、
3行目は sub.swf のルート1フレーム目に書かれた「 trace(this); 」の出力、
4行目が "output 3"になります。

僕は今まで onLoadInit が読み込みを開始したときのイベントだと勝手に勘違いしてました。
実際にはonLoadInitは読み込まれたswfの1フレーム目のスクリプトが実行された後に呼び出されるみたいです。
onEnterFrameは各フレームのスクリプトの一番最初に実行されるルールがここでも有効みたいなので、onLoadInitが呼び出される前(読み込まれたswfのスクリプトが実行されるよりも前)に実行されるみたいです。

それぞれ実行されるタイミングが違うので、意図的にこれらを使い分ければ便利かもしれないです。
今日は、前回のエントリー(PV3D と Box2D を組み合わせて使ってみた)で作った迷路FLASHの作り方について簡単に解説します。


迷路を生成するためにMazeクラスを作成
Maze.as

まず迷路を生成するクラスを作ります。 このクラスはプロパティ内に"1"と"0"の配列で迷路の情報を作成します。 画像は出力結果です。 このクラスは「C言語による最新アルゴリズム事典」を参考にさせてもらいました。


PV3DとMazeを組み合わせる
Cubic.as

先ほど作成したMazeクラスで生成した迷路の情報を元に、PV3DのCubeを配置します。
このCubic.asはPV3Dのサンプルについている「Cube」を元に編集したものです。
あとでボールを転がすので、試しにココでSphereクラスも使ってみます。
サイコロ柄なのは特に意味は無いです。
初めて使うので「MaterialsList」の関係とかを見るために6面を違う柄にしたかっただけです。
今回裏面は最終的に見えなくするので、無駄な処理を省くために接続面と裏面を消しています。


Box2DとMazeを組み合わせる
Ball.as

Cubeと同様に作成した迷路情報を元に四角と丸を配置します。
PV3Dが「x,y,z」の3軸なのに対して、Box2Dは「x,y」の2軸なので、z軸に対する重力は今回無視して
マウスの方向(x,y)に重力の座標を変更しています。
m_world.m_gravity.x = mouseX - 640 / 2;
m_world.m_gravity.y = mouseY - 360 / 2;
このBallクラスもBox2Dについているサンプル「HelloWorld」をもとにしています。


上記2つをさらに組み合わせる
Document.as

先ほど作成した Ball クラスと Cubic クラスを組み合わせます。
このときBallクラスで使用したDisplayObject(Sprite)はもういらないので削除します。
Box2Dは位置情報を持っているので、この情報を PV3D に反映させます。
あとはマウス座標に合わせて程よく傾ければ、傾いてる方向に転がってるように見えます。

全ソースファイルのダウンロードはこちら。
20080208_Maze.zip

巷でウワサの(?) Papervision3DBox2DFlashAS3 を試しに使ってみた。

どちらも使うのは今回が初めてなので、ちょいちょいいろんなブログを徘徊しつつ、
探り探りですが、簡単な迷路を作って、ボールを転がす。みたいなのを作ってみました。

最初に PV3D でオブジェクトの書き出しをするのにちょっと待たないといけないです。
3秒~10秒ほどかな?(マシンにもよるのだろうけども)
ちょっと重い気がするので別ページに置いておきます。
PV3D & Box3D :: MAZE
PV3D & Box3D :: MAZE
今回触ってみて困った点は、
  • 迷路はランダムに自動生成しているが、マス目が少ないとかなり単純なものになってしまい、逆に増やすと、PV3Dがオブジェクトを生成するのに時間がかかってしまう。
  • Box2Dで円が2つのオブジェクトに挟まれると、動かなくなってしまう。
この2点でした。

2つのライブラリを触ってみた感想は

PV3Dはさすが人気があるだけのことはあるなあと思いました。
ドキュメントもあるし、みんなブログに説明書いてくれてるし、で
これぐらいの物を作るぐらいならあんまり困らなかった。

一方Box2Dの方は、(たぶん)C++からの移植みたいだけども、
まだ移植しきれていないのか、バージョンアップによる変更のせいなのか
クラスによっては変数が定義されてないものを参照してたり、パッケージ名が
違ってたりしたのが気になった。

ソースとか迷路の詳細とかは、また今度。

FLASH CS3 / Windows XP sp2 で以下のJSFLコマンドを実行すると
エラーが表示されて、アプリケーションが強制終了してしまう。
fl.getDocumentDOM().library.updateItem();

エラーメッセージ
Flash.exe [4076]でハンドルされていない Win32 の例外が発生しました。
この例外の Just-In-Time デバッグに失敗し、次のエラーが発生しました:
インストールされたデバッガで Just-In-Time デバッグが有効になっていません。
Visual Studio では、[ツール]メニューの[オプション]を選択し、[デバッグ]にある[Just-In-Time]から
Just-In-Time デバッグを有効にできます。

詳細については、ドキュメントの Just-in-time デバッグのエラーについてのトピックを参照してください。
このコマンドはライブラリ内で読み込んだ画像やサウンドファイルを選択して、
右クリックで「更新」を選択するのと同じ機能を実行するもの。

同様のコマンドを FLASH 8 で実行しても、問題なく処理されるので
CS3のバグっぽい。

ちなみに「Just-In-Time デバッグ」を無効にしたり
レジストリを削除もしてみたが、そうすると今度は
エラーメッセージなしに強制終了されてしまった。

解決策が今のところ見当たらないので、FLASH 8 と共有で使う場合は
var fv = Number(String(fl.version).split(" ")[1].split(",")[0]);
if( fv < 9 ){
    fl.getDocumentDOM().library.updateItem();
}
として、CS3 では実行しないようにしといた方がいいかも。

便利なコマンドなだけに早く直してほしい。
いつもどっちがどっちか分からなくなる。 かなりどうでもいいメモ。
> (だいなり)
< (しょうなり)
今までHTMLをほとんど触ってこなかったので
あまり気にしてなかったので、メモ。

allowScriptAccess
参照:Adobe「HTML ページに埋め込まれた SWF からのリンクが機能しない場合がある」
http://support.adobe.co.jp/faq/faq/qadoc.sv?229684+002+3


AllowScriptAccess では、以下の 3 つの値を指定することができます。
− [always] : すべてのケースにおいて、SWF ファイルは HTML ページと通信することが可能です。
− [sameDomain] : SWF ファイルと HTML ページが同一ドメインに配置される場合のみ、SWF ファイルは HTML ページと通信することが可能です。Flash の初期設定で、HTML パブリッシュのテンプレートが出力する HTML コードの AllowScriptAccess は [sameDomain] に設定されています。これがセキュリティ上、望ましい設定です。
− [never] : すべてのケースにおいて、SWF ファイルは HTML ページと通信することができません。

wmode
参照:graffiti-blog「wmodeのクセ」
(http://blog.graffiti-web.org/archives/2006/04/wmode.html)


参照:Adobe「wmode を transparent に設定した際の注意点」
http://support.adobe.co.jp/faq/faq/qadoc.sv?228635+002


− [opaque] : 背景を不透明に設定する。
− [transparent] : 背景を透過に設定する(IE以外でも透過になる)

どちらを設定してもSWFの再生自体が遅くなることを防げるらしいが、IMEがバカになる。

というぼやきです。