Box2D 2.0.0のサンプルを2.1aで動かすための注意点

EaselJSのお勉強でBox2DWebを触ったので、その先を進めようとしたら意外とサンプルがない。JS版も基本的にBox2DFlashAS3と同じらしいんで、サンプルを漁ってみたもののどれも古くてそのままでは動かない。なんとか動くようにできたけど、色々変わってる点もがあり、それについて書かれた日本語ページを見つけられなかったので、今後のためにメモ。

※ Box2DFlashAS3 2.0.0 を 2.1a で動かすための変更点です。
まず、古いサンプルだとパブリッシュ設定がFlash Player9 になってる場合が多いけど、これだとこんなエラーが出ます。
行 8711046: 型が見つからないか、コンパイル時定数ではありません : b2Fixture。
これはFlash Player 10以上にすることで解決します(Flash Player11.4+Flash CS6で確認)。
次に Box2D.Dynamics.b2world クラスの b2wolrd メソッドの引き数が変わっています。
(2.0.0)world = new b2World(worldAABB, gravity, true);
(2.1a )world = new b2World(gravity, true);
それから Box2D.Collision.Shapes 配下のクラスが変わっています。
(2.0.0)b2CircleDef >> (2.1a)b2CircleShape
(2.0.0)b2PolygonDef >> (2.1a)b2PolygonShape
そして Box2D.Dynamics.b2world クラスの bodyを作る為のメソッドが変わっています。
(2.0.0)var floor:b2Body = world.CreateStaticBody(floorBodyDef);
(2.1a var floor:b2Body = world.CreateBody(floorBodyDef);
2.0.0では、作るbodyの種類毎に world.CreateStaticBody、world.CreateDynamicBody とメソッドがあったようですが、2.1a では1つになっています。で、staticとかdynamicの指定は、Box2D.Dynamics.b2BodyDef で設定するようになっています。
2.1a 
var bodyDef:b2BodyDef = new b2BodyDef();
bodyDef.type = b2Body.b2_dynamicBody;
また 2.0.0 では Box2D.Collision.Shapes に指定していた密度、摩擦係数、弾性(density,friction,restitution)は、2.1a では Box2D.Dynamics.b2FixtureDef に指定します。
(2.0.0)
var wheelShape:b2CircleDef = new b2CircleDef();
wheelShape.radius = 0.15;
wheelShape.density = 1;

(2.1a 
var wheelfixtureDef:b2FixtureDef = new b2FixtureDef();
wheelfixtureDef.shape = wheelShape;
wheelfixtureDef.density = 1;
よくサンプルで使われている Box2D.Dynamics.b2DebugDraw もメソッドが大幅に変わっています。「m_…」が「Set…」に変更されています。
(2.0.0)
debugDraw.m_sprite = this;
debugDraw.m_drawScale = DRAW_SCALE;
debugDraw.m_fillAlpha = 0.3;
debugDraw.m_lineThickness = 1;
debugDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;

(2.1a 
debugDraw.SetSprite(this);
debugDraw.SetDrawScale(DRAW_SCALE); 
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1)
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit | b2DebugDraw.e_pairBit);
最後に、物理シミュレーションを更新するための world.step() は、引数が2つから3つに変更されています。
(2.0.0)world.Step(1 / 24, 10);
(2.1a )world.Step(1 / 24, 10, 10);
そして Box2D.Dynamics.b2DebugDraw を使う際は、world.Step() を呼び出したあとに・・・
world.DrawDebugData();
が、必要なようです。
とりあえずココまでの対処で、2.0.0 のサンプルを 2.1a で動かすことができました。まだ理解し切れてるとはいえないので、誤り等ありましたらご指摘下さい。下記サンプルを書き換えて動作確認しました(MaxOSX10.7.6+Flash CS6+Box2DWeb 2.1a)。感謝。
【追記】2013.7.21 東京ひよこの会 第5回で、この内容を発表した際に見つけた誤りを修正しました。
(誤)(2.0.0)b2CircleDef >> (2.1a)b2PolygonShape
(正)(2.0.0)b2PolygonDef >> (2.1a)b2PolygonShape
 

Directorのdxrファイル

Directorで作られた古いCD-ROMから、画像を取り出す必要があって、しかもお約束通りdirファイルはなくて、CD-ROMの中のdxrファイルのみ…。いろいろ探してみたらコレが使えました。
動作環境はWin95になってるけど、XPで動きました。dxrファイルもダメなものもあったけど、今回の用途ではOKでした。試用も10日間できます。
あとMacで不可視ファイルを見る方法。これも役に立ちました。
この先あまり使うこともなさそうだけど、忘れた頃にやってきそうなので一応メモ。

EasleJS+Box2DWebで、床に角度をつける

野中さんのBox2DWeb+EaselJSのサンプルを組んでみた後に、床に角度をつけようとしたらハったのでメモ。要は、Box2Dでの角度=ラジアン、EaselJSでの角度=度数、ってことだったんだけど、コード書こうとして混乱してました。
bodyに角度をつける場合は・・・
 	//Box2Dでは、角度はラジアンで指定
  bodyDef.angle = Math.PI /180 *nAngle;
で、Tickerイベントの中でwolrdからbodyを取り出すときは、body.GetAngle()で取得した角度を度数に変換して・・・
  var body = world.GetBodyList();
  while(body){
     var myObject = body.GetUserData();
      if (myObject) {
        var position = body.GetPosition();
        myObject.x = position.x / SCALE;
        myObject.y = position.y / SCALE;

        //EaselJSでは、角度は度数で指定(ラジアン>度数変換)
        myObject.rotation = body.GetAngle() * (180/Math.PI);

      }
      //---次の剛体を取りだし
      body = body.GetNext();
  }
とやれば、物理計算と画面表示が正しく一致した角度になりました!実際に書いてみたコードはこちらにあります。

実際に角度つけたサンプルを見れば「ふんふん」となるようなことも、自分で書こうとすると意外にはまってしまうのは、経験の浅さかなと。

※事実誤認などありましたら、ご指摘ください。

CreateJSのマウスイベントでのthis参照

引き続き野中さんの記事(EaselJSのマウスクリックとドラッグ&ドロップ)のコードを書いていて、イベントハンドラからthisの参照した時に、何を指すのかがわからなかったのでテストしてみました。

 上の記事で作ったShapeに対して・・・
function overHandler(eventObject) {    console.log("over++++++++++++++++");

console.log("this>>"+this);
console.log("eventObject>>"+eventObject);
console.log("eventObject.target>>"+eventObject.target);

 }
こんな感じで、各イベントハンドラでログを書き出してみた結果です。
onClick
this>>[Shape (name=null)]
eventObject>>[MouseEvent (type=click stageX=98 stageY=46)]
eventObject.target>>[Shape (name=null)]
onDoubleClick
this>>[Shape (name=null)]
eventObject>>[MouseEvent (type=dblclick stageX=104 stageY=51)]
eventObject.target>>[Shape (name=null)]
onPress
this>>[Shape (name=null)]
eventObject>>[MouseEvent (type=mousedown stageX=98 stageY=46)]
eventObject.target>>[Shape (name=null)]
onMouseMove
this>>[MouseEvent (type=mousedown stageX=110 stageY=55)]
eventObject>>[MouseEvent (type=mousemove stageX=503 stageY=253)]
eventObject.target>>[Shape (name=null)]
onMouseUp
this>>[MouseEvent (type=mousedown stageX=98 stageY=46)]
eventObject>>[MouseEvent (type=mouseup stageX=98 stageY=46)]
eventObject.target>>[Shape (name=null)]
onMouseOver
this>>[Shape (name=null)]
eventObject>>[MouseEvent (type=mouseover stageX=115 stageY=55)]
eventObject.target>>[Shape (name=null)]
onMouseOut
this>>[Shape (name=null)]
eventObject>>[MouseEvent (type=mouseout stageX=119 stageY=66)]
eventObject.target>>[Shape (name=null)]

これらをまとめると・・・

  • onMouseMove,onMouseUpでは、thisは対となるMouseEvent(mousedown)を指す。
  • その他のマウスイベントでは、thisはshapeを指す。
ということのようです。
※easeljs:0.6.0で動作確認。
 
関連リンク

CreateJSでMouseOver/MouseOutを使う際の注意点

ついでなんで、合間にいじってたCreateJSのマウスイベントについて。

クリックは問題なく動いたんだけど、マウスオーバー/マウスアウトがうまく行かなくて填まりました。で、結局・・・
stage.enableMouseOver()

というメソッドを使って、明示的にonMouseOverとonMouseOutを使うことを宣言しないといけないらしいです。こちらの記事(EaselJSのMouseEventを理解しよう)を参考にしました。感謝。

あと、EaselJSのバージョンが0.6.0以降は、イベントハンドラでなくイベントリスナー推奨らしいので、その関連リンクも。
Flashな人にとっては、AS2.0 >> AS3.0的な流れですね。

CreateJSはじめる際の注意点

ようやく重い腰を上げて、CreateJSを触り始めました。

とりあえず参考にしたのは、当日の講義も聴いた野中さんのこの記事。
で、記事はわかりやすいんだけど。ライブラリのバージョンが上がってるので、その辺の注意点をメモ。

walk2_mc._SpriteSheet = new SpriteSheet({images: [“sprite_sheet.png”], frames: [[0,0,167,268,0,84.5,135],[167,0,167,268,0,84.5,135],[334,0,167,268,0,84.5,135],[0,268,167,268,0,84.5,135],[167,268,167,268,0,84.5,135],[334,268,167,268,0,84.5,135]]});

この「frames」に書かれている配列の2,3番目が幅(168)と高さ(268)になります。
去年の11月に聞いて、今頃触るっていうのもアレなんですけど、記事はたくさんあるけれど、バージョンの差違で同じようにハマル人もいるかもなので、一応メモしておきます。
※easeljs:0.6.0、soundjs:0.4.1、preloadjs:0.3.0で動作確認。