簡體   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