1

トップダウンゲームで単純なタイルベースの衝突システムを実装しましたが、コーナーを移動する際に問題が発生します。現在、私のプログラムはプレーヤーの中心点を取り、20pxの正方形のグリッド(交互の灰色の背景)にタイルを作成します。上、下、左、右のタイルに衝突がないかチェックし、見つかった場合は次のステージに移動します。

次の段階は、プレイヤーがタイル内のどこにいるかを確認することです。このために、私はgetCenterDistanceFromCurrentTile()(創造的な名前、私が知っている)と呼ばれる関数を持っています。これにより、タイルの中心点からプレーヤーの中心点までの距離のVector2i(xおよびy)が返されます。次に、これを次のように使用します。

  • 左側に壁タイルがあり、プレーヤーのx距離が0未満の場合(プレーヤーは現在のタイルの中心点の左側にあります)、プレーヤーは壁の隣のタイルのxに移動します。
  • 右側に壁があり、プレーヤーのx距離が> 0(現在のタイルの中心点の右側)である場合、プレーヤーは壁の隣のタイルのxに移動します。
  • これはY軸についても同じように続きます。

私の問題は対角線です。現在、対角線の衝突はチェックしていませんが、チェックする必要があるようです。私はすでにそれを実装しようとしましたが、プレイヤーはコーナーにぶつかるとジャンプします。プレーヤーx<0とプレーヤーy<0の上記の方法を一緒に使用していましたが、うまくいきませんでした。私は自分の問題をよりよく説明するためにいくつかの画像を作成しました。

問題のある画像1

この画像は、左側の衝突(青いタイルで示されている)とピンクのタイルがチェックされているが、衝突が見つからない状態で、衝突システムが正常に機能していることを示しています。緑のタイルはプレーヤーの現在のタイルを示し、赤い四角はプレーヤーの現在の場所を示します。

問題のある画像2

この画像は、私が抱えている問題を明確に示しています。ピンクの牌はどれも衝突していないので、プレイヤーのxとyをチェックする必要はありません。

ゲームでコーナーの衝突を確認するにはどうすればよいですか?

私の現在の衝突チェックコード。

public boolean isWall(Vector2i loc)
{
    return this.isWall(loc.x, loc.y);
}

public boolean isWall(int x, int y)
{
    if (x < 0) return true;
    if (y < 0) return true;
    if (y > map[0].length-1) return true;
    if (x > map.length-1) return true;
    return map[x][y];
}

public void phys(Player plr) {
    Vector2i playerTile = plr.getTile();
    // Left
    if (isWall(playerTile.x-1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x < 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Right
    if (isWall(playerTile.x+1, playerTile.y))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.x > 0)
        {
            plr.setX(playerTile.x*BLOCK_SIZE);
        }
    }
    // Up
    if (isWall(playerTile.x, playerTile.y-1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y < 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
    // Down
    if (isWall(playerTile.x, playerTile.y+1))
    {
        Vector2i distanceFromTile = plr.getCenterDistanceFromCurrentTile(true);
        if (distanceFromTile.y > 0)
        {
            plr.setY(playerTile.y*BLOCK_SIZE);
        }
    }
}
4

1 に答える 1

1

phys メソッドは、プレイヤーが壁に衝突しているかどうかに応じてブール値を返す可能性があります。次に、この関数の結果を使用して、移動する前のスペース内の以前の場所に戻るか、衝突していない場合は続行するかを決定できます。

これには、プレイヤーの周囲に隣接するすべての壁をチェックする必要があります。これにより、phys メソッドで衝突チェックを反復する、よりクリーンな方法が導入されます。

このような改善は次のようになります。

public boolean phys(Player plr)
{
    java.awt.Rectangle playerBounds = new java.awt.Rectangle(plr.x, plr.y, BLOCK_SIZE, BLOCK_SIZE);

    for (int y = 0; y < 3; y++)
    {
        for (int x = 0; x < 3; x++)
        {
            // Skip the tile the player is on assuming that he is not on a wall already
            if (x == 1 && y == 1) continue;

            java.awt.Rectangle bounds = new java.awt.Rectangle(/*tile at (x, y) xpos*/, /*tile at (x, y) ypos*/, BLOCK_SIZE, BLOCK_SIZE);

            if (bounds.intersects(playerBounds))
            {
                return true;
            }
        }
    }

    // Did not collide
    return false;
}
于 2013-01-08T00:42:14.177 に答える