边界矩形碰撞 - 球跳过桨的错误一侧

时间:2014-03-10 17:52:51

标签: c# xna collision-detection collision rectangles

我正在制作Pong游戏,我遇到了一个问题。当球(一个矩形)与球拍下方或上方的球拍(或球棒)碰撞时,我得到一个奇怪的错误,球进入矩形并左右 - 左 - 右达到高速(因为我添加了)加速)并在对面跳出来。我知道为什么会发生这个错误:

if (ballrec.Intersects(player1rec)
        && ball.x <= 20
        && ball.y + 20 >= player.y
        && ball.y <= player.y + 100) //checks the front rebound-here's the bug
{
    ball.vx *= -1; //changes x-direction
    if (ball.vx < 0)
        ball.vx -= 1; //increases x-velocity
    effect.Play();
    if (R.Next(4) == 0)
    {
        if (ball.vy < 0) ball.vy--;
        else ball.vy++; //increases y-velocity on a special occasion
    }
}
else
{
    if (ballrec.Intersects(player1rec))
    {
        ball.vy *= -1;
        effect.Play();
    }
}

ball.vy = velocity y-axis:我将它乘以-1以改变方向

效果=声音

错误:为了让球在球拍正面的任何位置反弹,它说球的下侧(+20)不得高于球拍的上侧而球的上侧必须不要低于球拍的下侧。然而,由于x坐标(ball.x <= 20,20 =球拍的宽度),前反弹效应消耗了球拍的顶部和底部,然后那里的反弹不起作用。

当我试图解决它时,我最好的非复杂解决方案(因为明年我开始上中学(我国14-18岁)并且不知道很多花哨的数学),我不知道得到一个好的解决方案(见下面)。

我的解决方案(我不满意):我将前方篮板所需的区域降低到ball.y&gt; = player.y和ball.y + 20&lt; = player.y + 100(长度)上下反弹工作,但如果球击中球拍的一角,同样的错误只出现在这种情况下球上下 - 上下移动。

我的问题:如何修复错误? 感谢您的时间!希望不会太久!

目前的解决方案(不完美):

if (ballrec.Intersects(player1rec)
        && ball.x <= 20
        && ball.y >= player.y
        && ball.y + 20 <= player.y + 100)
{
    ball.vx *= -1;
    if (ball.vx < 0)
        ball.vx -= 1;
    effect.Play();
    if (R.Next(4) == 0)
    {
        if (ball.vy < 0) ball.vy--;
        else ball.vy++;
    }
}
else
{
    if (ballrec.Intersects(player1rec))
    {
        ball.vy *= -1;
        effect.Play();
    }
}

1 个答案:

答案 0 :(得分:0)

解决方案1:检查速度矢量

一种解决方案是考虑Speep向量(ball.vx)的方向。 如果速度为负,则允许player1翻转球x速度(例如,向第二个玩家移向左侧屏幕,反之亦然) 如果这是一个简单的乒乓球比赛,那就完全没问题了:

// Player 1
if (ballrec.Intersects(player1rec)
    && ball.x <= 20
    && ball.y >= player.y
    && ball.y + 20 <= player.y + 100
    && ball.vx <= 0 ) //<--- Here
{
// .....
}

// Player 2
if (ballrec.Intersects(player2rec)
    // ....
    && ball.vx >= 0 ) //<--- Here
{
// .....
}

解决方案2:保存球的碰撞状态

另一个解决方案是保存当前的碰撞状态(碰撞或不碰撞,只有在此状态从不碰撞切换到碰撞时才翻转速度):

public class Ball
{
    public bool colliding = false;
}

//In Update of Ball/Game
bool player1Collision = ballrec.Intersects(player1rec)
    && ball.x <= 20
    && ball.y >= player.y
    && ball.y + 20 <= player.y + 100;
if( player1Collision && !ball.colliding )
{
    // Set state here, so reduce issues when there is a chance that different players can overlap
    ball.colliding = true;
    // .....
}

// Same for player 2,3,4,5 .....

//Update state for next frame
ball.colliding = player1Collision || player2Collision /* .... */;