在实现简单的乒乓球AI时,创建了两个球拍并出现闪烁

作为一个新程序员,我没有进行实际的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;}

然而,实际情况是这样的(我尝试使用PrtScn截屏,结果似乎暂停了游戏一微秒,只捕捉到了一个球拍而不是两个闪烁的球拍)。那么,我该怎么做才能让第二个球拍看起来像一个呢?

程序的完整代码:

Game1.cs

namespace Pong{  public class Game1 : Game  {    //变量    GraphicsDeviceManager graphics;    SpriteBatch spriteBatch;    //边界    Texture2D borders;    //球拍    Paddle p1 = new Paddle();    Paddle p2 = new Paddle();    //球    Ball ball = new Ball();    //位置    Vector2 bordersPos;    //构造函数    public Game1()        : base()    {        graphics = new GraphicsDeviceManager(this);        graphics.IsFullScreen = false;        graphics.PreferredBackBufferHeight = 800;        graphics.PreferredBackBufferWidth = 800;        //内容加载器        Content.RootDirectory = "Content";    }    //初始化    protected override void Initialize()    {        base.Initialize();    }    //加载内容    protected override void LoadContent()    {        spriteBatch = new SpriteBatch(GraphicsDevice);        //分配纹理        p1.texture = Content.Load<Texture2D>("paddle1");        p2.texture = Content.Load<Texture2D>("paddle1");        borders = Content.Load<Texture2D>("borders");        ball.texture = Content.Load<Texture2D>("ball");        //位置        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()    {    }    //更新    protected override void Update(GameTime gameTime)    {        //退出        if (Keyboard.GetState().IsKeyDown(Keys.Escape))            Exit();        //更新玩家控制        PlayerInput();        p1.Update();        p2.Update();        ball.Update();        //球拍碰撞        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);    }    //绘制    protected override void Draw(GameTime gameTime)    {        GraphicsDevice.Clear(Color.Black);        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);        //球拍        p1.Draw(spriteBatch);        p2.Draw(spriteBatch);        //边界        spriteBatch.Draw(borders, bordersPos, Color.White);        //球        ball.Draw(spriteBatch);        spriteBatch.End();        base.Draw(gameTime);    }    //玩家输入    public void PlayerInput()    {        //玩家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;        }    }    //球拍碰撞    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{    //变量    public Texture2D texture;    public Vector2 position;    public PlayerIndex pNumber;    public int width, height;    public float speed;    //构造函数    public Paddle()    {        texture = null;        position = Vector2.Zero;        pNumber = PlayerIndex.One;        width = 64;        height = 187;        speed = 10.0f;    }    //更新    public void Update()    {        //设置边界        if (position.Y <= 30)             position.Y = 30;        if (position.Y >= 800 - 217)            position.Y = 800 - 217;    }    //绘制    public void Draw(SpriteBatch spriteBatch)    {        spriteBatch.Draw(texture, position, Color.White);    }}

Ball.cs

namespace Pong{class Ball : Game{    //变量    public Vector2 position;    public Texture2D texture;    public int width, height;    public float speed;    public bool movingDownLeft, movingUpLeft, movingDownRight, movingUpRight;    //构造函数    public Ball()    {        Content.RootDirectory = ("Content");        speed = 6.0f;        width = 20;        height = 20;        movingDownLeft = true;        movingUpRight = false;        movingUpLeft = false;        movingDownRight = false;        position = Vector2.Zero;    }    //绘制    public void Draw(SpriteBatch spriteBatch)    {        spriteBatch.Draw(texture, position, Color.White);    }    //更新    public void Update()    {        //方向        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;        }        //球与墙的碰撞        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;        }    }}}

回答:

我从未使用过MonoGame,但这段代码:

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已经为你做了这件事)。现在看起来你的球拍移动速度会根据你的帧率而变化。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注