2012-02-25 53 views
0

我是XNA的首发者,我正在尝试制作pong游戏。
我已经能够做出一个乒乓球比赛,但所有的代码是在一个类。所以我想尝试添加一点OOP,我已经为球和班级制作了一堂课。在XNA/C中移动矩形的最佳方式#

球移动完美,但我似乎无法使球从球垫反弹。

这是我使用的代码:
要移动垫
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
现在我只是需要让我的工作boundries来解决,因为MathHelper.Clamp似乎并没有工作
更多信息

my code

此代码现在我的固定边界问题

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); 
    } 

回答

2

这立即站出来给我(从CheckBounce):

movement.X *= 1; 

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

此外,请考虑使用Rectangle.Contains/Intersects方法来简化一些碰撞代码,MathHelper.Clamp可以让您的划桨保持在边界内。由于您的方法可以工作,所以这仅仅是为了将来的参考,但利用XNA中有用的工具很不错。

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

Rectangle类所拥有的方法交叉,包含,它可以告诉你,如果是矩形相交的另一个矩形或含有一定点,分别。你说你的球只是一个左上角位置和一个纹理,但是我在你的碰撞中看到你也检查了球的半径。我想你会更容易为球定义一个矩形边界区域并使用相交方法来检查碰撞。这简化了您的碰撞代码:

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

相当简单,但不是完全safe--如果球设法远远不够进入桨该运动的一帧不会从桨的边界释放它,你被卡住永远颠倒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位置夹在边界顶部和边界底部之间减去矩形高度。最后一点通过考虑高度来保持矩形的底部不剪切边界的底部。

+0

+1,假设它像经典的Pong,其中的桨总是垂直对齐,那么只需反转X速度应该可以正常工作。 – 2012-02-25 20:34:43

+0

感谢您的快速响应!你能给我更多关于你提到的技巧的信息吗? 顺便说一句:这个球不是一个矩形,只是一个带有Vector2的Texture2D作为topLeft的位置 – GroundZero 2012-02-25 22:31:06

+0

该死!我的垫似乎不再移动了?我相信这是由_RecPad.Offset(0,speed)引起的; _但我不确定 – GroundZero 2012-02-25 22:32:48