在实现简单的乒乓球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

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

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