2Dプラットフォーマー(マリオタイプ)ゲームを作成しようとしていますが、衝突の適切な処理に問題があります。私はこのゲームをC ++で書いており、入力、画像の読み込み、フォントの読み込みなどにSDLを使用しています。また、グラフィックを表示するためにSDLと組み合わせてFreeGLUTライブラリを介してOpenGLを使用しています。
私の衝突検出方法は、AABB(Axis-Aligned Bounding Box)です。必要なのは、衝突が発生した側を検出し、衝突を適切に処理する簡単な方法です。したがって、基本的に、プレーヤーがプラットフォームの上部に衝突した場合は、プレーヤーを上部に移動します。側面に衝突がある場合は、プレーヤーをオブジェクトの側面に戻します。底に衝突がある場合は、プラットフォームの下にプレーヤーを再配置してください。
私が試してみました多く、このような浸透深さを見つけようと侵入深さによって後方プレーヤーを再配置するようにこれを行うためのさまざまな方法を、。残念ながら、私が試したことは何も正しく動作していないようです。プレイヤーの動きが非常にグリッチになり、望まないときにプレイヤーの位置を変えます。その理由の1つは、おそらくこれはとても単純なものだと思っているためですが、考えすぎています。
誰かが彼らが助けることができると思っている場合は、以下のコードを見て、可能であればこれを改善するのを助けてください。これを処理するためにライブラリを使用しないでください(自分で学びたいので)、または可能であればSAT(分離軸定理)のようなものを使用しません。よろしくお願いします!
void world1Level1CollisionDetection()
{
for(int i; i < blocks; i++)
{
if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==true)
{
de2dObj ballPrev;
ballPrev.coords[0] = ball.coords[0];
ballPrev.coords[1] = ball.coords[1];
ballPrev.coords[2] = ball.coords[2];
ballPrev.coords[3] = ball.coords[3];
ballPrev.coords[0] -= ball.xspeed;
ballPrev.coords[1] -= ball.yspeed;
ballPrev.coords[2] -= ball.xspeed;
ballPrev.coords[3] -= ball.yspeed;
int up = 0;
int left = 0;
int right = 0;
int down = 0;
if (ballPrev.coords[0] < block[i].coords[0] && ballPrev.coords[2] < block[i].coords[0] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1])) || ((ball.coords[1] < block[i].coords[3]) || ball.coords[3] < block[i].coords[3])))
{
left = 1;
}
if (ballPrev.coords[0] > block[i].coords[2] && ballPrev.coords[2] > block[i].coords[2] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1])) || ((ball.coords[1] < block[i].coords[3]) || (ball.coords[3] < block[i].coords[3]))))
{
right = 1;
}
if(ballPrev.coords[1] < block[i].coords[1] && block[i].coords[1] < ballPrev.coords[3] && ballPrev.coords[3] < block[i].coords[3])
{
up = 1;
}
if(block[i].coords[1] < ballPrev.coords[1] && ball
{
down = 1;
}
cout << left << ", " << right << ", " << up << ", " << down << ", " << endl;
if (left == 1)
{
ball.coords[0] = block[i].coords[0] - 18.0f;
ball.coords[2] = block[i].coords[0] - 2.0f;
}
else if (right == 1)
{
ball.coords[0] = block[i].coords[2] + 2.0f;
ball.coords[2] = block[i].coords[2] + 18.0f;
}
else if (down == 1)
{
ball.coords[1] = block[i].coords[3] + 4.0f;
ball.coords[3] = block[i].coords[3] + 20.0f;
}
else if (up == 1)
{
ball.yspeed = 0.0f;
ball.gravity = 0.0f;
ball.coords[1] = block[i].coords[1] - 17.0f;
ball.coords[3] = block[i].coords[1] - 1.0f;
}
}
if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==false)
{
ball.gravity = -0.5f;
}
}
}
このコードの一部が何を意味するかを説明するには:
ブロック変数は基本的に、ブロックまたはプラットフォームの量を格納する整数です。forループを使用してすべてのブロックをチェックしていますが、ループが現在オンになっている番号は整数iで表されています。座標系は少し奇妙に見えるかもしれませんので、説明する価値があります。coords [0]は、オブジェクトのx位置(左)を表します(x軸上で開始)。coords [1]は、オブジェクトのy位置(上)を表します(y軸上で開始)。coords [2]は、オブジェクトの幅とcoords [0](右)の幅を表します。coords [3]は、オブジェクトとcoords [1](下)の高さを表します。de2dCheckCollisionは、AABB衝突検出を実行します。ほとんどのゲームと同様に、アップは負のy、ダウンは正のyです。
うまくいけば、私が誰かが私をうまく助けるのに十分な情報を提供してくれた。欠落している重要な問題がある場合は、お知らせください。必要な情報を提供します。最後に、助けることができる人にとっては、コードを提供することは非常に役立ち、非常に高く評価されます。
あなたの助けをありがとう!
編集:私は、衝突前にボールが以前あった場所をチェックする新しいアルゴリズムでコードを更新しました。コーナーケースはその単一のプラットフォームで正しく動作しますが、オブジェクトの壁がある場合、それに対して実際にスライドできますが、スライド中に壁に向かって移動すると、それを通過し、基本的に壁の内側をブロックします。また、私が地面にいるとき、ボールが常に上下に動いているときに発生するジッタリング効果があります。
TheirPos-ourSize +- 1
1 を削除するのではなく、キャラクターを遠くに移動している問題であり、そうしている場合は1 を削除します。そのアルゴリズムを理解する方法がわからない場合は、私は喜んで助けてくれるでしょう、私は現時点では完璧です=](また、オブジェクトをチェックインする順序は何ですか?)