0

「ブレイクアウト」というゲームを作りました。ちょっとした楽しいサイドプロジェクト。

現在、私は通常ゲームを作成していないため、衝突処理は通常考えることではありません。

パドル、ボール、レンガをいくつか持っています。

今のところ、衝突が発生した場合 (前述の各オブジェクトの周りに長方形を描画します)、ボールの Y 値を -Y に変更するだけです。

これは、ボールが側面 (東または西) からレンガに当たった場合を除いて、正常に機能します。副作用はきれいではなく、ゲームプレイを台無しにします.

上記の手法の代わりに、これが発生した場合は X 値を -X に変更する必要があると安全に想定できると思います。

これまでのところ、私は持っています:if (ballRect.IntersectsWith(brickRect))

ballRectbrickRect各オブジェクトの周りの長方形です。

では、レンガの東の境界、西の境界などの周りに長方形を作成したらどうなるでしょうか。幅は約1ピクセルになると思います。

西または東の長方形で衝突が発生した場合、ボールの X 値は -X になります。およびその逆。

しかし、コーナーはどうですか?xコーナーを制御する長方形をランダムに選択する必要がありますか?

それとも、各コーナーの周りに長方形を作成する必要がありますか? 長方形は横に 1*1 です。衝突がある場合 => ボールの -x AND -y 値?

あなたの考えを共有してください。

これまでのプロセスは次のとおりです。

    foreach (var brick in Bricks)
    {
        if (brick.IsAlive)
        {
            var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight);
            if (ballRect.IntersectsWith(brickRect)) //Ball has hit brick. lets find out which side of the brick
            {
                var brickRectNorth = new Rectangle(brick.X, brick.Y + BrickHeight, BrickWidth, 1);
                var brickRectSouth = new Rectangle(brick.X, brick.Y, BrickWidth, 1);

                var brickRectEast = new Rectangle(brick.X, brick.Y, 1, BrickHeight);
                var brickRectWest = new Rectangle(brick.X + BrickWidth, brick.Y, 1, BrickHeight);

                if (ballRect.IntersectsWith(brickRectNorth) || ballRect.IntersectsWith(brickRectSouth))
                {
                    //STUFF that makes ball.y = -ball.y
                }
                if (ballRect.IntersectsWith(brickRectWest) || ballRect.IntersectsWith(brickRectEast))
                {
                    //STUFF that makes ball.x = -ball.x
                }
            }
        }
    }
4

1 に答える 1

2

長方形の交点を探すのではなく、実際のエッジを交差させます。コーナーでは、ボールが2つのエッジに同時に接触しているため、そのモーションベクトルは両方の影響を受けるはずです。

衝突検出用に単一の長方形を保持します。これにより、外側のループでテストする必要のある長方形の数が減りますが、レンガとの衝突が検出されたら、内側のループに移動して、それがどのエッジであるかを検出します。洗って。各エッジをテストし、それに応じてベクトルを調整すると、コーナーは無料で表示されます(最初の交差するエッジを見つけたときにループから抜け出さない限り)。

編集:更新された質問への回答:

実際、これは私が行う方法です(あなたのコードを考えると、これはC#3.0のように見えるので、以下で想定しています):

foreach(var brick in Bricks) {
    if(brick.IsAlive) {
        var brickRect = new Rectangle(brick.X, brick.Y, BrickWidth, BrickHeight);
        if(ballRect.IntersectsWith(brickRect)) {
            // Ball has hit brick.  Now let's adjust the ball's vector accordingly

            // Convenience variables.  Compiler will probably inline.
            var brickLeft = brick.X;
            var brickRight = brick.X + BrickWidth;
            var brickTop = brick.Y;
            var brickBottom = brick.Y + BrickHeight;

            var ballLeft = ball.X - ball.Radius;
            var ballRight = ball.X + ball.Radius;
            var ballTop = ball.Y - ball.Radius;
            var ballBottom = ball.Y + ball.Radius;

            // Test which vector(s) we need to flip
            bool flipX = (ballRight >= brickLeft || ballLeft <= brickRight);
            bool flipY = (ballTop >= brickBottom || ballBottom <= brickTop);

            // Flip the vectors (there are probably ways to optimize this,
            // too, but without seeing your code I can't tell).
            if(flipY) {
                // Stuff that makes ball.y = -ball.y
            }

            if(flipX) {
                // Stuff that makes ball.x = -ball.x
            }
        }
    }
}

基本的に、ポイントは、ボールが実際にレンガと交差することをすでに知っているので、単純なボックステストに単純化できるということです。これははるかに高速です。また、エッジに余分な長方形を作成する必要はありません。既存の長方形のエッジを使用するだけです。

于 2009-10-13T17:38:35.190 に答える