Box2DでActionScript物理プログラミング

第7回 円を落として星を飛び散らせる

この記事を読むのに必要な時間:およそ 3.5 分

Box2Dの様々な機能について説明してきましたが,そろそろBox2Dのマニュアルに書かれている主な機能の説明が一通り終わるので,今回で最終回とさせていただきます。最後のテーマはコンタクトリスナです。

コンタクトリスナを使うと,物と物がぶつかったことを検出できます。ピンボールではボールが様々なオブジェクトに当たったときに得点が入りますが,そういった部分の実装にコンタクトリスナを使うことができます。

サンプルについて

まずはサンプルのFlashをご覧ください。円を作るときのFlashに似ていますが,円が落下して床にぶつかると星が飛び散ります。前回DebugDrawを使わない方法を説明したばかりですが,今回は説明を簡単にするためにDebugDrawを使っています。

動作についての説明

このFlashでは,コンタクトリスナを使って画面内の全ての物体同士の衝突を検出しています。衝突を検出すると,その場所からくるくる回る星の絵を複数飛ばします。

コンタクトリスナでは衝突の強さを検出できるので,それに応じて飛ばす星の数を調整しています。激しく衝突するほど星の数を増やし,最大で10個としています。

全ての物体同士の衝突を見ているので,円同士の衝突でも星が飛び散ります。しかし,実際にそうしようとしても,飛ぶときと飛ばないときがあります。これはBox2D側の不具合ではないかと思われます。

サンプルファイルの構成

このFlashを作るためのプログラムと画像は以下のとおりです。本当はこれらのファイルだけではコンパイルできず,別のライブラリ(tweener)のソースが必要なのですが,これについては後述します。

今回のサンプルコードは,今までと少し違います。まず1つ目は,ActionScriptファイルが複数あることです。

メインのクラスが書かれているのはKiraKira.asです。mxmlcでコンパイルするときには,このファイルを指定すればFlashが生成されます。もう1つのContactListener.asは,コンタクトリスナを使うためのクラスです。

コンタクトリスナを使うときには,b2ContactListenerクラスを継承したクラスを作る必要があります。そのためのContactListenerクラスがContactListener.asに書かれています。

star.pngは,円が床に当たったときに飛び散る星の画像です。この画像は,前回説明したEmbed文を使ってFlashに埋め込まれます。

tweenerを使うには

もう1点,今までのサンプルと違うところは,tweenerを使っていることです。tweenerについては,プログラマのためのFlash遊び方の第6回,動きのあるFlashを作るにて取り上げられています。利用方法についてはそちらの説明をご覧ください。caurinaディレクトリをKiraKira.asなどと同じ階層に置けばコンパイルできるようになります。

コンタクトリスナの仕組み

サンプルプログラムの説明をする前に,まずは少し複雑なコンタクトリスナの仕組みについて説明します。

衝突を検出……というと,ActionScriptでのプログラミングに慣れている人なら,衝突検出用のイベントリスナを登録するのでは?と考えると思います。しかし,Box2Dは元々C++で書かれていたプログラムを移植したものなので,そこの考え方がかなり違います。

メソッドをオーバーライドして衝突を検出する

Box2Dで衝突を検出するには,以下のようにb2ContactListenerクラスの派生クラスを作り,Addメソッドをオーバーライドします。Addメソッドは,ワールド内の物体同士が衝突したときに呼び出されるメソッドです。

public class ContactListener extends b2ContactListener {
  public override function Add(point:b2ContactPoint):void {
    // 衝突検出時の処理
  }
}

このクラスの変数を作り,b2WorldクラスのSetListenerメソッドを使ってワールドに登録すると,実際にAddメソッドが呼び出されるようになります。

var contactListener:ContactListener = new ContactListener();
world.SetListener(contactListener);

その他のオーバーライドできるメソッド

b2ContactListenerクラスには,Addメソッドの他にもオーバーライドできるメソッドがあります。Addとまとめて整理すると以下のようになります。

Add
物体が衝突したときに呼び出されるメソッド
Persist
物体が衝突してから離れるまで繰り返し呼び出されるメソッド
Remove
物体が離れたときに呼び出されるメソッド

呼び出されるメソッド

呼び出されるメソッド

b2ContactPointについて

上で説明した3つのメソッドは,b2ContactPoint型の変数を引数に取ります。この変数は衝突に関するプロパティを持っており,何らかのアクションをするときにはこれらのプロパティの参照が欠かせません。

プロパティは数が多いので,よく使うものだけ説明します。詳しくはb2ContactPointクラスのソースを見てみてください。

position
物体が接触している点の座標。サンプルではこの場所から星を飛ばしています
normalForce
衝突の強さ。サンプルではこれに応じて星の数を決めています
shape1,shape2
接触している物体(b2Shape型の変数)。これを参照すれば衝突した物体に応じて動作を変えることができます

著者プロフィール

木村秀敬(きむらひでたか)

茨城高専,北陸先端大を卒業後,独立系ベンチャーにあこがれてjig.jpに就職。 ActionScript好きですが,根はコテコテのC/C++プログラマです。Flash/ActionScriptに興味のある方は是非Spark Projectへ。

コメント

コメントの記入