1

衝突検出のコードは機能しますが、プレイヤーとモンスターの速度を 1 以上に設定するとすぐに奇妙な結果が得られます。これを解決するにはどうすればよいですか?

速度 1 の場合

速度 1 の場合

速度 4 の場合

速度 4 の場合

私の衝突検出:

static boolean collisionDown(Entity e)
{
    for(Block i : Game.blocks)
    {
        Rectangle player = new Rectangle(e.getX(), e.getY() + e.getVelocity(), e.getWidth(), e.getHeight());
        Rectangle block = new Rectangle(i.getX(), i.getY(), size, size );
        if (player.intersects(block))
        {
            //e.goUp(1);
            return true;
        }
    }
    return false;
}

static boolean collisionUp(Entity e)
{
    for(Block i : Game.blocks)
    {
        Rectangle player = new Rectangle(e.getX(), e.getY()  - e.getVelocity(), e.getWidth(), e.getHeight());
        Rectangle block = new Rectangle(i.getX(), i.getY(), size, size);
        if (player.intersects(block))
        {
            return true;
        }
    }
    return false;
}

static boolean collisionRight(Entity e)
{
    for(Block i : Game.blocks)
    {
        Rectangle player = new Rectangle(e.getX() + e.getVelocity(), e.getY(), e.getWidth(), e.getHeight());
        Rectangle block = new Rectangle(i.getX(), i.getY(), size, size);
        if (player.intersects(block))
        {
            return true;
        }
    }
    return false;
}

static boolean collisionLeft(Entity e)
{
    for(Block i : Game.blocks)
    {
        Rectangle player = new Rectangle(e.getX() - e.getVelocity(), e.getY(), e.getWidth(), e.getHeight());
        Rectangle block = new Rectangle(i.getX(), i.getY(), size, size);
        if (player.intersects(block))
        {
            return true;
        }
    }
    return false;
}

衝突検出を使用する場所

void goUp(int v)
{
    if(!Block.collisionUp(this))
        y -= v;
}

void goDown(int v)
{
    if(!Block.collisionDown(this))
        y += v;
}

void goRight(int v)
{
    if(!Block.collisionRight(this))
        x += v;
}

void goLeft(int v)
{
    if(!Block.collisionLeft(this))
        x -= v;
}

ありがとうございました

4

2 に答える 2

3

ゲームの次の反復でキャラクターどこにいるのかを評価していると仮定すると、衝突方法は私には問題ないように見えます。ただし、衝突が発生した場合は、キャラクターをオフセットで移動して、衝突ボックスの外に移動し、有効な領域に戻して補正することに賭けます。速度が高くなると、この小さな副作用が拡大します。これらのメソッドを呼び出すすべての場所を再確認し、これらのメソッドが true を返したときに続くロジックに従います (主に Y 方向のもの)。

試してみるべき追加のことは、キャラクターの速度をさらに高くするか、その中間に上げることです。値を操作するときにキャラクターが遠ざかったり近づいたりする場合は、これが起こっている可能性が非常に高くなります。

ちなみに、すべてのメソッドでこの行に注意してください

Rectangle player = new Rectangle(e.getX(), e.getY()  - e.getVelocity(), e.getWidth(), e.getHeight());

この四角形は、メソッド呼び出し中に (ゲームにスレッドを実装していないと仮定して) 変更されないため、for ループの反復ごとに再作成すると時間がかかります。メソッドを次のように変更することを検討してください。

static boolean collisionDown(Entity e)
{
    Rectangle player = new Rectangle(e.getX(), e.getY() + e.getVelocity(), e.getWidth(), e.getHeight());
    for(Block i : Game.blocks)
    {
        Rectangle block = new Rectangle(i.getX(), i.getY(), size, size );
        if (player.intersects(block))
        {
            //e.goUp(1);
            return true;
        }
    }
    return false;
}
于 2013-09-12T19:50:58.920 に答える
1

衝突検出のために私が行ったことは、 というクラスを開発することCollissionDetectorです。次のようなメソッドのロジックが含まれています。

public boolean isColliding();
public boolean collided(Rectangular r1, Rectangular r2);

Rectangular は、1 つのメソッドを持つインターフェイスです。

public Rectangle getRectangle();

したがって、私のCollisionDetectorクラスは、呼び出されたインターフェイスを実装してRectangularを返すことができるものなら何でも使用できましたRectangle

衝突を検出するはずの一部のコードの問題は、同じ衝突を複数回報告することです。

私のコリジョン ディテクタでは、コリジョン ディテクタ オブジェクトは、コリジョンがいつ開始されたか、2 つのオブジェクトがまだ衝突しているかどうか、およびコリジョンがいつ終了したかを追跡します。

も持っていたようCollissionListenerです。これはすべて非常に複雑であることはわかっていますが、うまくいきました。には、次のCollisionListenerようなメソッドがありました。

public void CollissionStarted();
public void CollissionEnded();

SSCCE を提供できればと思います: http://sscce.orgですが、もうコードを持っていません。

于 2013-09-13T17:19:32.880 に答える