繁体   English   中英

在XNA / C#中移动矩形的最佳方法

[英]Best way to move a rectangle in XNA/C#

我是XNA的入门者,正在尝试制作乒乓球游戏。
我已经能够做一个乒乓球游戏,但是所有的代码都在一个类中。 因此,我想尝试添加一些OOP,并为球类和护垫类做了一类。

球运动得很好,但我似乎无法使球从护垫弹起。

这些是我使用的代码:
移动打击垫
Game1.cs

#region left
    if (_KBS.IsKeyDown(Keys.W) || _KBS.IsKeyDown(Keys.Z))
        Left.MoveUp();
    else if (_KBS.IsKeyDown(Keys.S))
        Left.MoveDown();
#endregion

#region right
    if (_KBS.IsKeyDown(Keys.Up))
        Right.MoveUp();
    else if (_KBS.IsKeyDown(Keys.Down))
        Right.MoveDown();
#endregion

pad.cs

public void MoveUp() {
    if (!paused)
        RecPad.Offset(0, -speed);

    CheckBorders();
}

public void MoveDown() {
    if (!paused)
        RecPad.Offset(0, speed);

    CheckBorders();
}

private void CheckBorders() {
    MathHelper.Clamp(recPad.Y, borders.Top, borders.Bottom - recPad.Height);
}

检查球是否弹跳
ball.cs

public void CheckBounce() {
    if ((myBounds.Intersects(left) && movement.X < 0) || (myBounds.Intersects(right) && movement.X > 0))
            movement.X *= -1;
}

public void Draw(SpriteBatch sBatch, Texture2D texture, Color color, Rectangle left, Rectangle right) {
    this.left = left;
    this.right = right;

    Move();

    sBatch.Begin();
    sBatch.Draw(texture, myBounds, color);
    sBatch.End();
}

pad.cs

public Rectangle RecPad {
    get { return recPad; }
    private set { recPad = value; }
}

Game1.cs

Ball.Draw(spriteBatch, ball, Color.White, Left.RecPad, Right.RecPad);

我似乎要恢复工作了
该问题似乎可以通过使用originel recPad而不是构造函数RecPad来解决。
现在我只需要使边界起作用,因为MathHelper.Clamp似乎不起作用
查看我的代码以获取更多信息

这段代码现在解决了我的边界问题

private void CheckBorders() {
        if (recPad.Top < borders.Top)
            recPad.Location = new Point(recPad.X, borders.Top);
        if (recPad.Bottom > borders.Bottom)
            recPad.Location = new Point(recPad.X, borders.Bottom - recPad.Height);
    }

这立即对我突出(从CheckBounce):

    movement.X *= 1;

可能是复制错误,或者您忘记输入'-'。

另外,请考虑使用Rectangle.Contains / Intersects方法简化一些碰撞代码,并使用MathHelper.Clamp来使桨划定界限。 由于您的方法可以使用,因此这仅供以后参考,但是最好利用XNA中有用的工具。

编辑:关于那些“有用的工具”:

Rectangle类具有Intersect和Contains方法,可以分别告诉您该矩形是与另一个矩形相交还是包含某个点。 您说您的球只是左上角的位置和纹理,但我发现在碰撞检查中您还检查了球的半径。 我认为您可以更轻松地为球定义Rectangle边界区域,并使用Intersects方法检查碰撞。 这将您的冲突代码简化为:

public void CheckBounce()
{
    if (myBounds.Intersects(LeftPaddle.Bounds) || myBounds.Intersects(RightPaddle.Bounds))
        movement.X *= -1;
}

相当简单,但也不是完全安全的-如果球设法移动到桨板中足够远的位置,以致一帧运动无法将其从桨板的边界中释放出来,那么您将永远被困在X速度反转的方向,从而产生“卡住”球效应。 因此,我们可以再添加一些检查代码来避免这种情况:

public void CheckBounce()
{
    if ((myBounds.Intersects(LeftPaddle.Bounds) && movement.X < 0) ||
     (myBounds.Intersects(RightPaddle.Bounds) && movement.X > 0))
        movement.X *= -1;
}

如果内联条件过于密集,我深表歉意。 这意味着,如果球向左移动并击中右桨,则将X反转。同样,如果球向右移动并击中左桨,则将X反转。这将消除“粘滞”。

现在,对于MathHelper.Clamp,在您的情况下,我将使用它来限制桨运动。 MathHelper.Clamp只是在一个上限和下限之间钳制一个值。 这等效于使用Math.Min,然后使用Math.Max。

private void CheckBorders()
{
    //clamps a       value  to a   min  and a           max
    MathHelper.Clamp(recPad.Y, borders.Top, borders.Bottom - recPad.Height);
}

这会将矩形的Y位置夹在边界的顶部之间,边界的底部减去矩形的高度。 最后一点通过考虑高度来防止矩形的底部修剪边界的底部。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM