タイルベースの2D衝突検出の問題


8

このチュートリアルhttp://www.tonypa.pri.ee/tbw/tut05.htmlに従って、タイルベースの世界でリアルタイムの衝突を実装しようとしています。

これらのプロパティのおかげで、エンティティの中心座標がわかります。

public float CenterX
{
    get { return X + Width / 2f; }
    set { X = value - Width / 2f; }
}
public float CenterY
{
    get { return Y + Height / 2f; }
    set { Y = value - Height / 2f; }
}

次に、すべてのフレームで呼び出されるプレーヤークラスのupdateメソッドに、次のコードがあります。

public override void Update()
{
    base.Update();

    int downY = (int)Math.Floor((CenterY + Height / 2f - 1) / 16f);
    int upY = (int)Math.Floor((CenterY - Height / 2f) / 16f);
    int leftX =     (int)Math.Floor((CenterX + Speed * NextX - Width / 2f) / 16f);
    int rightX = (int)Math.Floor((CenterX + Speed * NextX + Width / 2f - 1) / 16f);

    bool upleft = Game.CurrentMap[leftX, upY] != 1;
    bool downleft = Game.CurrentMap[leftX, downY] != 1;
    bool upright = Game.CurrentMap[rightX, upY] != 1;
    bool downright = Game.CurrentMap[rightX, downY] != 1;

    if(NextX == 1)
    {
        if (upright && downright)
           CenterX += Speed;
        else
           CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
    }
 }

downY、upY、leftX、およびrightXは、それぞれ、最低のY位置、最高のY位置、左端のX位置、右端のX位置を見つける必要があります。チュートリアルではgetMyCorners関数が次のパラメーターで呼び出されるため、+ Speed * NextXを追加します。

getMyCorners (ob.x+ob.speed*dirx, ob.y, ob);

GetCellXおよびGetCellYメソッド:

public int GetCellX(float mX)
{
    return (int)Math.Floor(mX / SGame.Camera.TileSize); 
}
public int GetCellY(float mY)
{
    return (int)Math.Floor(mY / SGame.Camera.TileSize); 
}

問題は、壁に当たっているときにプレーヤーが「ちらつく」ことです。コーナーの1つだけに当たる壁に重なる可能性があるため、コーナーの検出は正しく機能しません。何が悪いのかわかりません。チュートリアルでは、ob.xおよびob.yフィールドは私のCenterXおよびCenterYプロパティと同じであり、ob.widthおよびob.heightはWidth / 2fおよびHeight / 2fと同じである必要があります。ただし、それでも機能しません。

ご協力いただきありがとうございます。


プレーヤーがその場に着いたら衝突をテストしていて、衝突した場合は反発しているのか、それとも次の手が衝突かどうかをテストしているのか?
kyndigs

キーを押したときに現在のプロセスを中断する更新機能にキープレスチェックを追加することをお勧めします。次に、プレーヤーが「ちらつき」ているときにキーを押して、デバッガーをウォークスルーします。(数字に何が起こっているかに注意を払います)ちらつくときに数字に何が起こっているかを調べてみてください。
Michael Coleman

回答:


1

いくつかの提案がありますが、実行してデバッグするための完全なコードがないため、問題が修正されるかどうかはわかりません。

このコードでは:

if(NextX == 1)
{
    if (upright && downright)
       CenterX += Speed;
    else
       CenterX = (Game.GetCellX(CenterX) + 1)*16 - Width / 2f;
}

elseステートメントは、オブジェクトが移動してはいけないのに、オブジェクトを移動しています。
オブジェクトを壁にぴったりと合わせようとしていると思いますが、計算が正しくない可能性があります。
elseステートメントをコメントアウトしても、オブジェクトはまだちらつきますか?

計算は(幅/ 2f)を減算するので少し疑わしく見え、CenterXのセット演算子は同じ減算を再度実行します。

私が指摘したいもう1つのことは、コードをわかりやすくするために、CenterXのプロパティで値を前後に計算させましたが、コードにはまだ同じ計算が繰り返し散らかっています。
これは問題の一部である可能性があります。いずれにせよ、私はいくつかのプロパティをさらに作成し、それらすべてに対して1つの標準を確立することをお勧めします。たとえば、Centerを格納されたプロパティにして、それから他を計算します。

public float CenterX
{
    get { return X; }
    set { X; }
}

public float LeftX
{
    get { return CenterX - Width / 2f; }
    set { CenterX = value + Width / 2f; }
}

public float RightX
{
    get { return CenterX + Width / 2f; }
    set { CenterX = value - Width / 2f; }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.