「くままり」で使用したBox2D AS3テクニックin work

 
date:2009.10.23   posted by:sakuma
 

弊社で製作しmixiアプリとして公開させていただいている「くくまり」は、主にFlash ActionScript3を用いて開発しました。その中でもゲームの根幹部分を担っている2D物理演算処理については、「Box2D」という物理演算ライブラリを使用しています(実際に使用しているのはBox2DのAS3移植版)。ボールの落下速度、衝突時の跳ね返りといった処理はすべてこのライブラリを使用して実現しています。

以前「Drop Burger」を製作した際もこのライブラリを利用したのですが、今回はより発展的な使い方をしています。開発中は主にネットで解説記事を探して問題解決していましたが、中には参考ドキュメントが見つからず苦労した部分がありましたので、その箇所について解説をしておきたいと思います。同じ事でお悩みの方がいましたらぜひ参考にして下さい。

なおBox2Dの基本的な使い方に関してはこの記事では解説しませんので、これから勉強しようという方は以下の記事を参考にしていただけるとよいと思います。

・ 「特集:Box2DでActionScript物理プログラミング|gihyo.jp」

 

1.生成したオブジェクトに固有の属性(ID)を持たせる

「くままり」では落下するボールに種類があり、それぞれグラフィック、重さ、大きさなどに違いがあります。Box2Dで扱える物体オブジェクト(b2body)には固有IDや属性といった概念がないため、これらを実装するには一工夫必要です。b2bodyオブジェクトには「m_userData」という空のオブジェクトが用意されているので、ここにMovieClipオブジェクトを作成して、そこに必要な属性を入れていきます。

newBall.m_userData = new MovieClip();
newBall.m_userData.id = 'panda';
newBall.m_userData.flag = false;
newBall.m_userData.enable = true;

こんな感じです。m_userDataに作成するオブジェクトのデータ型はSprite型でもString型でも大丈夫ですが、複数の属性を持たせる事を考えるとMovieClip型が一番使いやすいでしょう。もちろんライブラリ内のMCのクラス名を指定してもOKです。くままりではIDの他にXY座標やボールのレベル(リフティング回数)などを持たせています。これをEnterFrameイベント中の処理分岐に使うわけです。

 

2.反発の強さ(ベクトル)を操作する

「くままり」では自機とボールの衝突の際、マウスクリックで一瞬反発力が強まり、より勢いよくはじき飛ばせるという仕様を取り入れています。通常ではb2Bodyに設定されたdensity(密度)・restitution(反発計数)・friction(摩擦係数)を元に物理運動が再現されます。これらを動的に動かす事も可能ではありますが、物体に初速度を与える処理を実現したい場合はこの方法では難しいため、別の方法をとる必要があります。

b2Bodyクラスには「b2Vec2」というオブジェクトがあり、ここには物体の運動ベクトルが格納されています。この値を操作する事で、物体に初速度を与えたり、勢いを強める、進行方向を変えるといった処理が可能になります。

var vec:b2Vec2 = cbb.m_shape1.m_body.GetLinearVelocity();
if (vec.Length() < minimumBallVec) vec.Multiply(minimumBallVec / vec.Length());
if (vec.Length() > maximumBallVec) vec.Multiply(maximumBallVec / vec.Length());
vec.Multiply(myBallStatus.restitution);
cbb.m_shape2.m_body.SetLinearVelocity(vec);

b2BodyのGetLinearVelocityメソッドでベクトルを受け取り、SetLinearVelocityメソッドで計算し直したベクトルを設定します。b2Vec2クラスに計算に使えるメソッドがいくつか設定されているので、それを使うとよいでしょう。詳しくはソースファイル、ドキュメントを参照下さい。
「くままり」では何度も衝突させているとボールの勢いが弱まって、自機とボールがぶつかってもバウンドしなくなるという問題があったため、ベクトルの大きさに最小値(minimumBallVec)を設ける事で勢いが弱まった状態でも一定量以上バウンドさせるようにしました。またこの例では自機に反発力(myBallStatus.restitution)のパラメーターを設けています。反発力は通常1ですが、マウスをクリックする事で一瞬2に設定され、この間に衝突したボールのベクトルにその計数を乗算しています。この反発力にTweenMaxを使って変化を付け、自然にバウンドするよう調整しました。

 

3.衝突時に処理が重なる仕様を回避する。

Box2Dでオブジェクト同士の衝突を検出するには「b2world.m_contactList」を使用します。基本的にはEnterFrameイベント中で以下のようなforループを回して使用します。

for (var cbb:b2Contact = world.m_contactList; cbb; cbb = cbb.m_next) {
  trace(cbb.m_shape1.m_body.m_userData.id
      + ' : ' + cbb.m_shape2.m_body.m_userData.id);
}

これで衝突したボールのIDをTraceできます。出力をみれば分かりますが、「A:B」と「B:A」のような順序違いはひとつの衝突として見なされ重複しません。
ただここでひとつ問題が発生します。m_contactListに格納される判定リストは「衝突した瞬間」ではなく「衝突と言っていいくらい近い距離にいる」という基準で取得されているようで、フレーム数が細かいと1度の衝突で2、3回のイベントを重複して実行したり、接触している状態だと延々とイベントを実行し続けてしまったりします。これはBox2Dの仕様上の問題であるため、実装で回避するしかありません。

くままりではこれを「衝突後に数フレームの処理間隔を与える」事で解決しています。

const crashInterval:int = 5;

function enterFrameEvent (e:Event) {
    // 全b2Bodyオブジェクトを走査
    for (var b:b2Body = world.GetBodyList(); b; b = b.GetNext()) {
        // 衝突インターバルをデクリメント
        if (b.GetUserData() is MovieClip && b.GetUserData().crashinterval > 0) {
            b.GetUserData().crashinterval--;
        }
    }

    // 衝突イベント処理
    for (var cbb:b2Contact = world.m_contactList; cbb; cbb = cbb.m_next) {
        // 長ったらしいので代入
        var u_data1:MovieClip = cbb.m_shape1.m_body.m_userData;
        var u_data2:MovieClip = cbb.m_shape2.m_body.m_userData;
        // 衝突オブジェクトの処理間隔が0なら何かする
        if (u_data1.crashinterval <= 0 && u_data2.crashinterval <= 0) {
            // ここで何かする
        }
        // 処理間隔を設定
        u_data1.crashinterval = u_data2.crashinterval = crashInterval;
    }
}

こうする事で衝突処理の重複を回避できました。「くままり」の場合、crashIntervalの値は調整した結果5になりましたが、この値はフレームレートなどによって変わってくると思います。

 

4.衝突したオブジェクトの種類により処理を分岐する

Box2Dは基本的には『動く物体』と『動かない物体』の2種類でしかオブジェクトを判別しておらず、たとえばブロック崩しのようなゲームでも「壁」と「自機のバー」は同じ『動かない』オブジェクトですが、ボールがそれぞれと衝突した際の反応は異なっています。たとえば衝突音を変化させたい、反発度を変えたい場合などは処理を区別しなくてはなりません。
これはオブジェクトの種類によりIDを割り振って処理分岐を作る事で実現できます。項目1の内容が出来ていればもうほとんど解決なのですが、「くままり」ではそれぞれのオブジェクトに割り振ったIDを判別してSwitch文で分岐処理しています。

for (var cbb:b2Contact = world.m_contactList; cbb; cbb = cbb.m_next){
  if (cbb.m_shape1.m_body.m_userData && cbb.m_shape2.m_body.m_userData) {

    var u_data1:MovieClip = cbb.m_shape1.m_body.m_userData;
    var u_data2:MovieClip = cbb.m_shape2.m_body.m_userData;

    switch (u_data1.id) {
      // 自機との衝突
      case 'myball':
      if (u_data2.crashinterval <= 0) {
        /* ここで何かする */
      }
      break;

      // 床との衝突
      case 'floor':
      if (u_data2.crashinterval <= 0) {
        /* ここで何かする */
      }
      break;

      case 'wleft':
      case 'wright':
      if (u_data2.crashinterval <= 0) {
        /* ここで何かする */
      }
      break;

      case 'border':
      if (u_data2.crashinterval <= 0) {
        /* ここで何かする */
      }
      break;

      // ボール同士の衝突
      default:
      if (u_data2.crashinterval <= 0) {
        /* ここで何かする */
        // 衝突インターバルを設定
        u_data1.crashinterval = u_data2.crashinterval = crashInterval;
      }
      break;
    }
  }
}

以上のコードをEnterFrameイベント中で実行しています。毎フレーム実行する処理なので、負荷に気をつけながらコンパクトなコードに仕上げるのがよいでしょう。

 
"lab"で関連する記事一覧 (シーケンスで表示する)
•2010.07.05-iPadアプリ「Twin Striker」をリリース in news
•2010.06.06-The Css AwardsのSite of the Dayに選ばれました in work
•2010.06.06-iPhoneアプリ「TWIN STRIKER」をリリース! in news
•2010.06.04-each関数を使ったテキスト上下中央揃え in work
•2010.05.31-オフィシャルサイトで使う予定だった技術 in work
•2010.05.31-オフィシャルサイトで使った技術その3 in work
•2010.05.31-オフィシャルサイトで使った技術その2 in work
•2010.05.28-Androidアプリ「Twin Striker」をリリース! in news
•2010.05.26-リンク集 in development
•2010.05.26-事例(Twin Strikerのワークフロー) in development
•2010.05.26-Coronaトラブル対策 in development
•2010.05.26-Coronaと他Projectの比較 in development
•2010.05.26-Tips4. iPhone3GSとAndroid1.6の動作の違い in development
•2010.05.26-Tips3. iPhoneで気をつけるべきこと in development
•2010.05.26-Tips2. Androidで気をつけるべきこと in development
•2010.05.26-Tips1. Flashからの変換 in development
•2010.05.26-Coronaの環境構築編 in development
•2010.05.26-Coronaの紹介編 in development
•2010.05.26-『日本代表に応援メッセージを送ろう!』携帯版リリース in news
•2010.05.25-オフィシャルサイトで使った技術その1 in work
•2010.05.25-おっぱいw-cup携帯版をリリースしました! in news
•2010.05.24-会津大学 ソフトウェアスタジオ キックオフ編 in work
•2010.05.24-会津大学 ソフトウェアスタジオ 準備編 in work
•2010.05.22-サッカー日本代表に応援メッセージを送ろう! in news
•2010.05.21-DSNオフィシャルサイトリニューアル in news
•2010.05.17-Processing.jsを使った万華鏡デモ in work
•2010.05.14-CSS3のアニメーション機能 in development
•2010.05.07-複数打ったはずのマーカーが1つしか表示されない in work
•2010.05.07-TwitterSearchAPIのフィードをパースする in work
•2010.04.24-HTML5&CSS3のデモを作成しました in work
•2010.02.16-JSパウワァ&ドラッグ機能の改善ついて in work
•2010.01.08-Processingおもしろい&使えるライブラリ10 in work
•2010.01.04-HTML5を学ぶつもりならスマートフォンを買おう in work
•2009.12.02-マルチタッチディスプレイ vol.02 in work
•2009.10.23-「くままり」で使用したBox2D AS3テクニック in work
•2009.10.22-mixiアプリモバイル作成前に見ておくべき10のまとめ in work
•2009.10.21-mixiアプリの公開手順 in work
•2009.10.15-mixiアプリ「鉄血王女と待受騎士団」をリリース in news
•2009.10.14-mixiアプリのパズルゲームについて in work
•2009.09.07-雑誌ウェブデザイニングに掲載されました! in work
•2009.08.27-mixiアプリ「くままり」をリリース in news
•2009.08.26-くままるのmixiアプリ『くままり』登場 in work
•2009.05.27-もっとがほしいDSN in work
•2009.04.16-Webページで角丸のボックスを作る方法あれこれ in work
•2009.03.02-みんなが大好きjQuery in work
•2009.02.27-マルチタッチディスプレイ vol.01 in work
•2009.02.20-ニールセンのユーザビリティ10原則 in work
•2009.02.11-センサー講座 Spe.001 Wiimote Whiteboard in work
•2009.02.06-センサー講座 Lec.003 Phidgetsインストール in work
•2009.02.06-エラスティックレイアウト in work
•2009.02.05-Jakob Nielsen博士 in work
•2009.01.30-固定幅レイアウト vs. リキッドレイアウト その2 in work
•2009.01.29-センサー講座 Lec.002 phidgetsの購入 in work
•2009.01.24-固定幅レイアウト vs. リキッドレイアウト その1 in work
•2009.01.20-センサー講座 Lec.001 どれを選ぶ? in work
 
 
"mixi"で関連する記事一覧 (シーケンスで表示する)
•2010.05.05-勇者マイミク in services
•2010.05.05-くままり。 in services
•2009.10.23-「くままり」で使用したBox2D AS3テクニック in work
•2009.10.22-mixiアプリモバイル作成前に見ておくべき10のまとめ in work
•2009.10.21-mixiアプリの公開手順 in work
•2009.10.21-mixiアプリの登録手順 in work
•2009.10.15-mixiアプリ「鉄血王女と待受騎士団」をリリース in news
•2009.10.14-mixiアプリのパズルゲームについて in work
•2009.08.27-mixiアプリ「くままり」をリリース in news
•2009.08.26-くままるのmixiアプリ『くままり』登場 in work
 
 
"social-app"で関連する記事一覧 (シーケンスで表示する)
•2010.05.17-位置情報サービスに必要な技術まとめ in work
•2010.05.07-複数打ったはずのマーカーが1つしか表示されない in work
•2010.05.05-勇者マイミク in services
•2010.05.05-くままり。 in services
•2009.10.23-「くままり」で使用したBox2D AS3テクニック in work
•2009.10.22-mixiアプリモバイル作成前に見ておくべき10のまとめ in work
•2009.10.21-mixiアプリの公開手順 in work
•2009.10.21-mixiアプリの登録手順 in work
•2009.10.15-mixiアプリ「鉄血王女と待受騎士団」をリリース in news
•2009.10.14-mixiアプリのパズルゲームについて in work
•2009.08.27-mixiアプリ「くままり」をリリース in news
•2009.08.26-くままるのmixiアプリ『くままり』登場 in work
 
 
"socolab"で関連する記事一覧 (シーケンスで表示する)
•2010.07.05-iPadアプリ「Twin Striker」をリリース in news
•2010.06.06-The Css AwardsのSite of the Dayに選ばれました in work
•2010.06.06-iPhoneアプリ「TWIN STRIKER」をリリース! in news
•2010.05.28-Androidアプリ「Twin Striker」をリリース! in news
•2010.05.26-リンク集 in development
•2010.05.26-事例(Twin Strikerのワークフロー) in development
•2010.05.26-Coronaトラブル対策 in development
•2010.05.26-Coronaと他Projectの比較 in development
•2010.05.26-Tips4. iPhone3GSとAndroid1.6の動作の違い in development
•2010.05.26-Tips3. iPhoneで気をつけるべきこと in development
•2010.05.26-Tips2. Androidで気をつけるべきこと in development
•2010.05.26-Tips1. Flashからの変換 in development
•2010.05.26-Coronaの環境構築編 in development
•2010.05.26-Coronaの紹介編 in development
•2010.05.26-『日本代表に応援メッセージを送ろう!』携帯版リリース in news
•2010.05.25-おっぱいw-cup携帯版をリリースしました! in news
•2010.05.24-会津大学 ソフトウェアスタジオ キックオフ編 in work
•2010.05.24-会津大学 ソフトウェアスタジオ 準備編 in work
•2010.05.22-サッカー日本代表に応援メッセージを送ろう! in news
•2010.05.21-DSNオフィシャルサイトリニューアル in news
•2010.05.17-Processing.jsを使った万華鏡デモ in work
•2010.05.17-位置情報サービスに必要な技術まとめ in work
•2010.05.17-Message Bottleをリリースしました in news
•2010.05.13-おっぱいW-cupをリリースしました in news
•2010.05.07-TwitterSearchAPIのフィードをパースする in work
•2010.05.05-メッセージボトル in services
•2010.05.05-おっぱいワールドカップ in services
•2010.05.05-DJ Turndroid in services
•2010.05.05-勇者マイミク in services
•2010.05.05-くままり。 in services
•2010.04.24-HTML5&CSS3のデモを作成しました in work
•2010.04.01-Androidアプリ「DJ Turndroid」をリリース! in news
•2010.02.16-JSパウワァ&ドラッグ機能の改善ついて in work
•2010.01.08-Processingおもしろい&使えるライブラリ10 in work
•2010.01.04-HTML5を学ぶつもりならスマートフォンを買おう in work
•2009.12.02-マルチタッチディスプレイ vol.02 in work
•2009.10.23-「くままり」で使用したBox2D AS3テクニック in work
•2009.10.22-mixiアプリモバイル作成前に見ておくべき10のまとめ in work
•2009.10.21-mixiアプリの公開手順 in work
•2009.10.21-mixiアプリの登録手順 in work
•2009.10.15-mixiアプリ「鉄血王女と待受騎士団」をリリース in news
•2009.10.14-mixiアプリのパズルゲームについて in work
•2009.09.14-Googleサーバー活用法[ファイル置き場] in work
•2009.09.07-雑誌ウェブデザイニングに掲載されました! in work
•2009.08.27-mixiアプリ「くままり」をリリース in news
•2009.08.26-くままるのmixiアプリ『くままり』登場 in work
•2009.05.27-ブログ向け音楽プレイヤー「DSN Player」 in news
•2009.05.27-もっとがほしいDSN in work
•2009.03.20-会津しこんがasahi.comの動画に in news
•2009.03.02-みんなが大好きjQuery in work
•2009.02.28-居酒屋“会津しこん”がasahi.comで紹介されました in work
•2009.02.27-マルチタッチディスプレイ vol.01 in work
•2009.02.20-ニールセンのユーザビリティ10原則 in work
•2009.02.11-センサー講座 Spe.001 Wiimote Whiteboard in work
•2009.02.06-センサー講座 Lec.003 Phidgetsインストール in work
•2009.02.06-エラスティックレイアウト in work
•2009.02.05-Jakob Nielsen博士 in work
•2009.01.30-固定幅レイアウト vs. リキッドレイアウト その2 in work
•2009.01.29-センサー講座 Lec.002 phidgetsの購入 in work
•2009.01.24-固定幅レイアウト vs. リキッドレイアウト その1 in work
•2009.01.20-センサー講座 Lec.001 どれを選ぶ? in work
•2009.01.17-会津しこんで取材 in work
•2008.12.22-地域SNSから生まれた居酒屋「会津しこん」 in news
 
 
Copyright © TheDesignium inc. powered by WordPress & mootools.
Relative Keyword|lab mixi social-app socolab