2012-03-23 11 views
2

Androidでは、SurfaceViewを使用して単純な2Dゲームを表示します。ビットマップ(.png)アルファ(ゲームオブジェクトを表す)がキャンバスに描画されます。AndroidのSurfaceViewのキャンバスでのビットマップによる衝突検出

ここで、簡単で正確な衝突検出を行いたいと思います。これらのビットマップがオーバーラップしているかどうかをチェックするのは簡単です。

しかし、これらのビットマップに透明領域がある場合、どのようにして衝突をチェックするのですか?私の挑戦は、2つのボールが衝突するかどうかを検出することです。それらは幅と高さの両方でビットマップ全体を塗りつぶしますが、4つの辺すべてに四角形の円として透明な領域があります。

ボールがの実際にと衝突した場合にのみ、衝突を検出する最も簡単な方法は何ですか。周辺のビットマップボックスではありませんか?

できるだけ多くのポイントの座標をボールのアウトラインに格納する必要がありますか? Androidは衝突をチェックする際にアルファチャンネルを「無視する」ことができますか?

答えて

7

ボールコリジョンの場合、コリジョン検出を実行することができます。これはピクセル単位の検出よりもはるかに高速です。最初のボールには2つのボール中心(x1、y1)と(x2、y2)と半径r1、2番目のボールにはr2が必要です。今、ボールの中心間の距離が小さいか、半径の和の等しいならば、ボールが衝突している:

colide = sqrt((x1-x2)^2+(y1-y2)^2)<=r1+r2 

を少しより高速な方法は、この値の2乗を比較することです:

colide = (x1-x2)^2+(y1-y2)^2<=(r1+r2)^2 
+1

ありがとうございます!ボールの例では、これはおそらく完璧な解決策です。より一般的な解決策(ピクセル単位の検出など)に感謝するつもりだが、これは私のせいだ。 – caw

2

それはずっとです既存のライブラリ、例えばAndEngineを簡単に再利用することができます。私はそれがSurfaceViewと一緒に使用することができるかどうかわからない。この記事をチェック:Pixel Perfect Collision Detection for AndEngine

+0

スプライトを使用したくないので、おそらくこのコードの部分のみを使用するのが最良の方法でしょうか?これは重要な部分ですか? https://github.com/m5/andengine-pixel-perfect/blob/master/src/com/qwerjk/andengine/collision/PixelPerfectBitMask.javaまた、ピクセルごとのビットマップの色をチェックする可能性はありませんか?私は本当に色(アルファではない)がどこにあるか確認し、このようにして実際のオブジェクトの輪郭を決定することができました。 – caw

9

私が考えることのできるもう1つの方法は、Pathを使って構築できる単純なオブジェクトで動作します。

あなたはその境界のパスで表現されている2つのオブジェクトを持っていたら、あなたはこれを試すことがあります。

Path path1 = new Path(); 
path1.addCircle(10, 10, 4, Path.Direction.CW); 
Path path2 = new Path(); 
path2.addCircle(15, 15, 8, Path.Direction.CW); 

Region region1 = new Region(); 
region1.setPath(path1, clip); 
Region region2 = new Region(); 
region2.setPath(path2, clip); 

if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) { 
    // Collision! 
} 

あなたがパスとしてあなたのオブジェクトを持っていたら、あなたは直接drawPath()を使用してそれらを描くことができます。また、パスを使用して移動を実行することもできます。

+1

ありがとう、これは、非円形オブジェクトのための本当に興味深い便利なソリューションです!とにかく、私は実際に 'クリップ'が何であるかを考え出しませんでした。 – caw

+2

私の理解から、上記のコードの変数 "クリップ"はパスの境界ボックスでなければなりません。一般的な目的のために使用します リージョンクリップ=新しい地域(0、0、layoutWidth、layoutHeight); レイアウトの幅と高さは、キャンバスやアクティビティなどのサイズにすることができます。 –