在实现简单的Pong AI时,会创建两个拨片并闪烁

时间:2014-08-08 11:48:30

标签: c# artificial-intelligence monogame 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;
}

然而,这种情况发生了(好吧,我尝试用PrtScn拍摄一个屏幕,然后它停下来让游戏暂停一微秒并捕获一个单独的桨而不是两个闪烁的桨) 那么我该怎样做才能使桨2显示为一个?

完整的计划守则:

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;
        }
    }
}
}

2 个答案:

答案 0 :(得分:1)

我从未使用过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为您执行此操作)。现在看来,根据您的帧速率,您的拨片上的移动速度会更高。

答案 1 :(得分:1)

  1. PaddleGame不得继承GameGameComponent而不是?)。应该只有一个Game对象。

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