在执行简单的《Pong》AI时,我们会创建两个摇杆并闪烁

本文关键字:创建 我们 闪烁 两个 Pong 简单 执行 AI | 更新日期: 2023-09-27 18:17:01

所以,我是一个新程序员,而不是做实际的人工智能执行,我使用以下解决方案,使球拍在右边跟着球:

if(ball.position.Y > p2.position.Y)
{
    p2.position.Y += ball.position.Y;
}
else if (ball.position.Y < p2.position.Y)
{
    p2.position.Y -= ball.position.Y;
}

然而,这种情况发生(好吧,我试着用PrtScn截取屏幕截图,它似乎暂停游戏一微秒,捕捉一个桨而不是两个闪烁的桨)我怎么做才能让两个桨看起来像一个呢?

程序完整代码:

Game1.cs

namespace Pong
{
  public class Game1 : Game
  {
    //Variables
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    //Borders
    Texture2D borders;
    //Paddles
    Paddle p1 = new Paddle();
    Paddle p2 = new Paddle();
    //Ball
    Ball ball = new Ball();
    //Positions
    Vector2 bordersPos;
    //Constructor
    public Game1()
        : base()
    {
        graphics = new GraphicsDeviceManager(this);
        graphics.IsFullScreen = false;
        graphics.PreferredBackBufferHeight = 800;
        graphics.PreferredBackBufferWidth = 800;
        //Content Loader
        Content.RootDirectory = "Content";
    }
    //Initialize
    protected override void Initialize()
    {
        base.Initialize();
    }
    //Load Content
    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        //Assigning Textures
        p1.texture = Content.Load<Texture2D>("paddle1");
        p2.texture = Content.Load<Texture2D>("paddle1");
        borders = Content.Load<Texture2D>("borders");
        ball.texture = Content.Load<Texture2D>("ball");
        //Positions
        p1.position.X = 50;
        p1.position.Y = graphics.GraphicsDevice.Viewport.Height / 2 - (p1.height / 2);
        p2.position.X = graphics.GraphicsDevice.Viewport.Width - 50 - p2.width;
        p2.position.Y = graphics.GraphicsDevice.Viewport.Height / 2 - (p2.height / 2);
        bordersPos.Y = 0;
        bordersPos.X = 0;
        ball.position.X = 800 / 2 - ball.width / 2;
        ball.position.Y = 800 / 2 - ball.height / 2;
    }
    protected override void UnloadContent()
    {
    }
    //Update
    protected override void Update(GameTime gameTime)
    {
        //Exit
        if (Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();
        //Update Player Controls
        PlayerInput();
        p1.Update();
        p2.Update();
        ball.Update();
        //Paddle Collision
        if (padCol1())
        {
            if (ball.movingDownLeft)
            {
                ball.movingDownRight = true;
                ball.movingDownLeft = false;
            }
            else if (ball.movingUpLeft)
            {
                ball.movingUpRight = true;
                ball.movingUpLeft = false;
            }
        }
        if (padCol2())
        {
            if (ball.movingDownRight)
            {
                ball.movingDownLeft = true;
                ball.movingDownRight = false;
            }
            else if (ball.movingUpRight)
            {
                ball.movingUpLeft = true;
                ball.movingUpRight = false;
            }
        }
        //AI
        if(ball.position.Y > p2.position.Y){
            p2.position.Y += ball.position.Y;
        }
        else if (ball.position.Y < p2.position.Y)
        {
            p2.position.Y -= ball.position.Y;
        }
        base.Update(gameTime);
    }
    //Draw
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);
        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
        //Paddles
        p1.Draw(spriteBatch);
        p2.Draw(spriteBatch);
        //Borders
        spriteBatch.Draw(borders, bordersPos, Color.White);
        //Ball
        ball.Draw(spriteBatch);
        spriteBatch.End();
        base.Draw(gameTime);
    }
    //Player Input
    public void PlayerInput()
    {
        //Player 1
        if (Keyboard.GetState(p1.pNumber).IsKeyDown(Keys.W)) 
        {
            p1.position.Y -= p1.speed;
        }
        else if (Keyboard.GetState(p1.pNumber).IsKeyDown(Keys.S))
        {
            p1.position.Y += p1.speed;
        }
    }
    //Paddle Collision
    public bool padCol1()
    {
        if (ball.position.Y >= p1.position.Y && ball.position.X > p1.position.X && ball.position.X < (p1.position.X + p1.width) && ball.position.Y < (p1.position.Y + p1.height))
        {
            return true;
        }
        else
            return false;
    }
    public bool padCol2()
    {
        if (ball.position.Y >= p2.position.Y && ball.position.X > p2.position.X && ball.position.X < (p2.position.X + p2.width) && ball.position.Y < (p2.position.Y + p2.height))
        {
            return true;
        }
        else
            return false;
    }
}
}

Paddle.cs

namespace Pong
{
class Paddle : Game
{
    //Variables
    public Texture2D texture;
    public Vector2 position;
    public PlayerIndex pNumber;
    public int width, height;
    public float speed;
    //Constructor
    public Paddle()
    {
        texture = null;
        position = Vector2.Zero;
        pNumber = PlayerIndex.One;
        width = 64;
        height = 187;
        speed = 10.0f;
    }
    //Update
    public void Update()
    {
        //Set Boundaries
        if (position.Y <= 30) 
            position.Y = 30;
        if (position.Y >= 800 - 217)
            position.Y = 800 - 217;
    }
    //Draw
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, Color.White);
    }
}

}Ball.cs

namespace Pong
{
class Ball : Game
{
    //Variables
    public Vector2 position;
    public Texture2D texture;
    public int width, height;
    public float speed;
    public bool movingDownLeft, movingUpLeft, movingDownRight, movingUpRight;
    //Constructor
    public Ball()
    {
        Content.RootDirectory = ("Content");
        speed = 6.0f;
        width = 20;
        height = 20;
        movingDownLeft = true;
        movingUpRight = false;
        movingUpLeft = false;
        movingDownRight = false;
        position = Vector2.Zero;
    }
    //Draw
    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, Color.White);
    }
    //Update
    public void Update()
    {
        //Directions
        if(movingUpLeft){
            position.Y -= speed;
            position.X -= speed;
        }
        if (movingDownLeft)
        {
            position.Y += speed;
            position.X -= speed;
        }
        if (movingUpRight)
        {
            position.Y -= speed;
            position.X += speed;
        }
        if (movingDownRight)
        {
            position.Y += speed;
            position.X += speed;
        }
        //Ball Wall Collision
        if(movingUpLeft && position.Y <= 30)
        {
            movingDownLeft = true;
            movingUpLeft = false;
        }
        //1
        else if (movingDownLeft && position.X <= 0)
        {
            movingDownRight = true;
            movingDownLeft = false;
        }
        //2
        else if (movingUpLeft && position.X <= 0)
        {
            movingUpRight = true;
            movingUpLeft = false;
        }
        //3
        else if (movingDownLeft && position.Y >= 800 - 45)
        {
            movingUpLeft = true;
            movingDownLeft = false;
        }
        //4
        else if (movingDownRight && position.X >= 800 - width)
        {
            movingDownLeft = true;
            movingDownRight = false;
        }
        //5
        else if (movingUpRight && position.Y <= 30)
        {
            movingDownRight = true;
            movingUpRight = false;
        }
        //6
        else if (movingDownRight && position.Y >= 800 - 45)
        {
            movingUpRight = true;
            movingDownRight = false;
        }
        //7
        else if (movingUpRight && position.X >= 800 - width)
        {
            movingUpLeft = true;
            movingUpRight = false;
        }
    }
}
}

在执行简单的《Pong》AI时,我们会创建两个摇杆并闪烁

我从来没有使用过一夫一妻制,但这:

if(ball.position.Y > p2.position.Y)
{
    p2.position.Y += ball.position.Y;
}
else if (ball.position.Y < p2.position.Y)
{
    p2.position.Y -= ball.position.Y;
}

总是超调,然后触发下一次更新。

你为什么不这样做呢:

p2.position.Y = ball.position.Y;

编辑:你可能还应该让你的输入帧率独立(除非MonoGame为你这样做)。现在看来,你会得到更高的移动速度在你的桨取决于你的帧率。

  1. PaddleGame不能继承Game(而应继承GameComponent)。应该只有一个Game对象

  2. 你应该用Vector2 speed来代替你的布尔值和复杂的逻辑来描述球的速度,并在球击中某物时否定它的X或Y。