0

私は XNA のスターターで、ピンポン ゲームを作ろうとしています。
ピンポン ゲームを作成できましたが、すべてのコードが 1 つのクラスにまとめられていました。そこで、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);

パッドが機能するように見えた
問題は、コンストラクタ 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);
    }
4

1 に答える 1

2

これはすぐに私に際立っています (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;
}

かなり単純ですが、完全に安全というわけではありません。ボールが 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 位置が固定されます。その最後のビットは、高さを考慮して、長方形の下部が境界線の下部を切り取らないようにします。

于 2012-02-25T19:57:13.853 に答える