2011-09-02 9 views
12


これは私の最初の投稿ですので、どんな災害でもお詫び申し上げます。
私はOpenGL ES 2.0とAndroid 2.3の使い方で簡単なアクションゲームを開発しています。私が現在取り組んでいる私のゲームフレームワークは、3次元世界に存在する2次元スプライトに基づいています。もちろん私の世界のエンティティは、想像上の位置、フロート[]マトリックス、OpenGLテクスチャハンドル、アンドロイドのビットマップハンドルの形で回転する値などの情報を持っています(後者が必要なのかどうかはわかりませんOpenGlマシンを使ったラスタライズですが、当分の間は私の便宜のためにそこにあります)。これは簡単に背景ですが、今問題の問題になっています。
現在、どのオブジェクト(ここではOGLテクスチャ、またはAndroidビットマップ)をサンプリングする必要があるかわからないため、ピクセルベースの衝突検出に悩まされています。つまり、私は既にAndroidのビットマップを試そうとしましたが、ビットマップの外で読むことに比べて多くの実行時クラッシュが発生しました。もちろん、ビットマップからピクセルを読み取れるようにするには、正しく回転したスプライトを得るために、 Bitmap.createメソッドを使用しました。ここでは、コードスニペットです:
AndroidでのOpenGLES 2.0でのピクセルベースの衝突検出の問題

android.graphics.Matrix m = new android.graphics.Matrix(); 
if(o1.angle != 0.0f) {   
    m.setRotate(o1.angle); 
    b1 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, false); 
} 

問題に追加する、あるいは主要な問題であるかもしれないもう一つの問題は、(四角形が両方のオブジェクトのための相互の2次元空間を示す)交差点の私の矩形が構築されるということですOpenGLマトリクスの使用で計算された2つの境界ボックスの部分から、 Matrix.multiplyMV機能(以下のコード)を使用しています。それらの2つのAndroidとOpenGLマトリクス計算メソッドが等しくないかもしれませんか?あなたのコードにバグがあることが

Matrix.rotateM(mtxRotate, 0, -angle, 0, 0, 1); 

// original bitmap size, equal to sprite size in it's model space, 
// as well as in world's space 
float[] rect = new float[] { 
    origRect.left, origRect.top, 0.0f, 1.0f, 
    origRect.right, origRect.top, 0.0f, 1.0f, 
    origRect.left, origRect.bottom, 0.0f, 1.0f, 
    origRect.right, origRect.bottom, 0.0f, 1.0f 
}; 

android.opengl.Matrix.multiplyMV(rect, 0, mtxRotate, 0, rect, 0); 
android.opengl.Matrix.multiplyMV(rect, 4, mtxRotate, 0, rect, 4); 
android.opengl.Matrix.multiplyMV(rect, 8, mtxRotate, 0, rect, 8); 
android.opengl.Matrix.multiplyMV(rect, 12, mtxRotate, 0, rect, 12); 

// computation of object's bounding box (it is necessary as object has been 
// rotated second ago and now it's bounding rectangle doesn't match it's host 
float left = rect[0]; 
float top = rect[1]; 
float right = rect[0]; 
float bottom = rect[1]; 
for(int i = 4; i < 16; i += 4) { 
    left = Math.min(left, rect[i]); 
    top = Math.max(top, rect[i+1]); 
    right = Math.max(right, rect[i]); 
    bottom = Math.min(bottom, rect[i+1]); 
}; 
+0

一般的に言えば、OpenGLはグラフィック専用です。スクリーンに表示するためにそれらの変形*コピーを作る以外は、あなたのゲーム/ワールド座標に触れさせてはいけません。つまり、自分の持つ境界ボックスは、自分のコードを使って計算する必要があります。そして、ピクセルベースの物理システムに注意してください:)物理的にやりとりしないアイテム(それに触れると消えるアイテムは、箇条書きやアイテムのピックアップ、またはタッチ直後に死亡した場合)。 –

+0

その答えをありがとう。私が達成したいと思った結果は、円と箱に基づくものよりも良い衝突をすることでした。これは、おそらく、計算上高価なため、ピクセルの衝突が十分でないことは事実です。最近、私は「凸型」と呼ばれるものについて読みました。衝突システムの動作を向上させるためにそれらを使用する可能性があります – cplusogl

+1

ピクセルごとの警告は、私がそれを使って遊んでいたことが主な原因でした。学校スタイルのプラットフォーマ、そしてそれが正しいと感じなかったことを理解しました。適切なテクニック(最初はAABBのみの衝突、グリッドシステムや動的なクワッドツリーなどの空間分割情報によって減少させた後、特殊な白黒のみのコリジョンマスクを使用して、計算上の複雑さを大幅に減らすことができます。オーバーラップ)。凸型は間違いなく良い方法であり、2次元のインタラクションだけで3Dアートを置き換えることができます。 –

答えて

0

乾杯、

最初のノート。 Matrix.multiplyMV()をソースベクトルとデスティネーションベクトルが同じで使用することはできません(関数はソースベクトルで上書きするx座標を正しく計算しますが、y、z、wを計算するには元のxが必要です座標 - これには欠陥があります)。また、行列変換を実行するために複雑なコードを必要としないため、最初の検出衝突ステップにバウンディング球を使用する方が簡単です。

次に、衝突検出。ビットマップやテクスチャから読み込むべきではありません。あなたがしなければならないことは、あなたのオブジェクトのためのシルエットを作ることです(それはかなり簡単です、シルエットは単に位置のリストです)。その後、(凸ではない)シルエットを満たす凸オブジェクトを作成する必要があります。それは、例えば、耳クリッピングアルゴリズム。それは最速ではないかもしれませんが、実装が非常に簡単で、一度だけ実行されます。凸オブジェクトを取得したら、行列を使って座標を変換し、あなたの世界との衝突を検出することができます(あなたが使用できる光線三角形の交差点についての素晴らしい記事がたくさんあります)。ベースの衝突検出。

私はそれが助けてくれることを願っています...

+0

ああ、私は他のmultiplyMV呼び出しを確認しなければならないでしょう、それを指摘してくれてありがとう。それでも、funnily十分なアプリケーションの動作は、multiplyMVの不適切な使用のために何か不具合を提示したことはありません... 凸形状については、私は主題を深く見なければならないでしょう。どうもありがとう! – cplusogl