1

私のゲームでは、プレイヤーは迷路をナビゲートします。壁との適切な衝突検出を行う方法がわかりません。特定のエリアにとどまるための衝突検出を行うのは簡単です:

if (x > rightWallX - playerWidth) x = rightWallX - playerWidth;
if (x < leftWallX) x = leftWallX;
//...

しかし、多くの壁の衝突検出をどのように行うのでしょうか?

(のように)修正せずに単純な衝突検出を行うことはできますif (intersecting) return true;が、これを正しく修正することはできません。x古いものを保存してyリセットすると、

  1. オブジェクトが実際に壁に触れることはありません
  2. オブジェクトが上がることができるが、右にブロックされている場合、オブジェクトは上がらず、移動しません。

迷路での衝突検出はどのように行われますか?

4

3 に答える 3

1

衝突検出を解決したら、衝突を修正する最も簡単な方法は、衝突するオブジェクトがなければ、アクターがいる場所に最も近い有効な位置にアクターを移動することです。これは慣性がないことを前提としていますが、迷路のようなゲームやトップダウンのマップ クローリング ゲームには十分です。

計算をさらに単純化したい場合は、アクターxまたはy座標を変更した方がよいかどうかを検出することに限定できます。アクターに軸に沿った長方形のヒット ボックスがあり、すべての障害物も軸に沿った長方形である場合 (最も単純なケース)、この仮定は確かに正しいです。ただし、他の場合には満足のいく結果が得られない場合があります (潜在的なアーティファクト: 斜めの壁を滑空することによる速度のブースト - ほとんどの迷路ゲームではそうではありません)。

複数の衝突が同時に発生する可能性があることに注意してください (2 つの壁を押す)。アクターが交差する 2 つの壁の間に鋭角がない場合 (たとえば、すべての障害物が軸に沿って配置され、十分な間隔がある場合)、各衝突を順番に修正するだけで十分です。

于 2013-01-03T04:00:49.423 に答える
0

わかりましたので、私は現在 2D のトップダウン ビュー ゲームを作成していますが、どのように迷路を作成したのかわかりません。ただし、私のゲームでは、私のレベルは Tile[][] tiles = new Tile[levelWidth][levelHeight]; から作成されます。配列。私が衝突検出を処理した方法は、周囲のタイルをチェックして、それらがしっかりしているかどうかを確認することでした。

これが私の getTile メソッドです。

public Tile[][] getTile(int x, int y) {
    if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
    return new VoidTile();
} else {
    return tiles[x][y];
}
}

私の Tile.java クラスには、タイルがソリッドかどうかを返す isSolid() メソッドがあります。すべてのタイルは私の Tile.java を拡張するため、このメソッドを継承し、コンストラクターでオーバーライドします。前に言ったように、あなたが私と同じスタイルのレベル実装を使用しているかどうかはわかりません。ただし、このようにすることをお勧めします:)

個人的には、スプライトの衝突検出に .intersects() および .contains() メソッドを使用することはあまり好きではありません。主にボタンなどに使用しています。

わかりました、私の player.java クラスには checkBlockedDirection(int x, int y) メソッドがあり、次のようになります。

    public void checkBlockedDirection(int x, int y) {
    boolean u = map.getTile(x, y - 1).isSolid();
    boolean d = map.getTile(x, y + 1).isSolid();
    boolean l = map.getTile(x - 1, y).isSolid();
    boolean r = map.getTile(x + 1, y).isSolid();

    if (u) {
        uBlocked = true;
        System.out.println("up tile blocked");
    } else {
        uBlocked = false;
    }
    if (d) {
        dBlocked = true;
        System.out.println("down tile blocked");
    } else {
        dBlocked = false;
    }
    if (l) {
        lBlocked = true;
        System.out.println("left tile blocked");
    } else {
        lBlocked = false;
    }
    if (r) {
        rBlocked = true;
        System.out.println("right tile blocked");
    } else {
        rBlocked = false;
    }
}

次に、プレーヤーの更新方法でこれを持っています

public void tick() {
    float dx = 0;
    float dy = 0;

    if (input.up.isPressed()) {
        direction = 0;
    } else if (input.down.isPressed()) {
        direction = 2;
    } else if (input.left.isPressed()) {
        direction = 3;
    } else if (input.right.isPressed()) {
        direction = 1;
    } else {
        direction = 4; // standing
    }

    checkBlockedDirection((int)x, (int)y);


    if (input.up.isPressed() && y > 0 && !uBlocked) {
            dy += -speed;
    } else if (input.down.isPressed() && y < map.getHeight() - 1 && !dBlocked) {
            dy += speed;
    } else if (input.left.isPressed() && x > 0 && !lBlocked) {
            dx += -speed;
    } else if (input.right.isPressed() && x < map.getWidth() - 1 && !rBlocked) {
            dx += speed;
    }
    x += dx;
    y += dy;

}

基本的には、上下左右のブロックがソリッドかどうかをチェックするだけです。それらが固い場合は動かず、固くない場合は目的の方向に移動できます。

これが役立つかどうかはわかりませんが、この種のグリッド衝突検出に対する私の見解です:)

お役に立てれば :)

楽しみ

于 2013-01-03T04:28:06.060 に答える