0

C++ と SDL で 2 つの rect 間の衝突を計算するにはどうすればよいですか? また、プレーヤーがこの rect を通過できないようにするには (つまり、一方の rect がもう一方の rectを通過できないようにする) にはどうすればよいですか?

プレーヤーを停止するとplayeryvel = 0、プレーヤーの Y 速度が 0 になり、通過できなくなります。私の問題は、他の四角形を通る動きを止めたいときに、これがすべての垂直方向の動きを止めることです。

私の現在のコードは、という名前の関数を使用していますcheck_collision(SDL_Rect, SDL_Rect)。これが私の使用法と実際の機能のコードです。

// This loops through a vector, containing rects.
for (int i=0; i<MAP::wall.size(); i++)
{
    std::cout << i << std::endl;
    cMap.FillCustomRect(MAP::wall.at(i), 0xFFFFFF);
    if (check_collision(cMap.wall.at(i), cDisplay.getPlayer(playerx, playery)))
    {
        exit(0); // It exits just as an example to show if there actually is a collision
    }
}


bool check_collision( SDL_Rect A, SDL_Rect B )
{
    //The sides of the rectangles
    int leftA, leftB;
    int rightA, rightB;
    int topA, topB;
    int bottomA, bottomB;

    //Calculate the sides of rect A
    leftA = A.x;
    rightA = A.x + A.w;
    topA = A.y;
    bottomA = A.y + A.h;

    //Calculate the sides of rect B
    leftB = B.x;
    rightB = B.x + B.w;
    topB = B.y;
    bottomB = B.y + B.h;

     //If any of the sides from A are outside of B
    if( bottomA <= topB )
    {
        return false;
    }

    if( topA >= bottomB )
    {
        return false;
    }

    if( rightA <= leftB )
    {
        return false;
    }

    if( leftA >= rightB )
    {
        return false;
    }

    //If none of the sides from A are outside B
    return true;
}
4

4 に答える 4

3

フレームごとに、プレイヤーを衝突点から遠ざけるだけです。ブール値のテスト (衝突するかどうか) は必要ありません。衝突が発生した場合は、プレイヤーの位置を調整する必要があります。

  1. プレーヤーの位置を更新します (位置 += 速度 * 時間);
  2. 衝突が発生した場合は、衝突が発生しないようにプレイヤーを衝突点から遠ざけます。

壁などに沿って「スライド」できるため、これは非常にうまく機能します。これを行うには、接触点、交差の深さ、交差の方向 (つまり、プレイヤーを押すべき方向) を見つける必要があります。立ち去る)。

もちろん、プレーヤーをどこまで動かすかを計算する必要がありますが、2D では非常に簡単に計算できます。

2 つの長方形がどのくらい重なるかを計算する必要があります。次に、プレイヤーの長方形を最も重なる方向 (x または y) に押します (それらが等しい場合を除き、x または y 方向のみ)。

于 2012-02-28T19:43:16.783 に答える
2

move関数に衝突チェックを追加。新しい位置を (移動されたかのように) コリジョン関数のチェックに渡します。移動関数で衝突が発生する場合は false を返し、移動しない場合は true を返します。

于 2012-02-28T21:52:54.583 に答える
1

事後に衝突を捕らえているようです。ほとんどの場合、プレーヤーを長方形に移動しているため、後続の衝突チェックは常にtrueを返します。これを修正する方法はいくつかありますが、衝突が発生した後ではなく、発生する前に衝突をキャッチして防止するのが最も簡単だと思います。

プレーヤーが落下していて、フレームごとにプレーヤーの位置を更新するとします。プレーヤーの位置を変更する前に、新しい位置が長方形と交差するかどうかを確認する必要があります。新しい位置が長方形と交差する場合は、プレーヤーが長方形の端に接触するが交差しないように、プレーヤーが移動する距離を変更します(この距離をステップと呼びます)。

于 2012-02-28T19:25:41.193 に答える