Reputation: 23
So, me being a new programmer, instead doing actual AI implementation, I used the following solution for making paddle on the right follow the ball:
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;
}
However this happens (okay I tried taking a screencap with PrtScn and it semmed to pause the game for a microsecond and capture a single paddle instead of two flickering ones) So what can I do to make the paddle 2 appear as one?
Full Code of Program:
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;
}
}
}
}
Upvotes: 2
Views: 707
Reputation: 1987
I've never used MonoGame but this:
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;
}
Will always overshoot, then trigger the next update.
Why don't you just do:
p2.position.Y = ball.position.Y;
EDIT: You should probably also make your input frame rate independent (unless MonoGame does this for you). It seems now you'll get higher movement speed on your paddles depending on your framerate.
Upvotes: 1
Reputation: 34285
Paddle
and Game
must not inherit from Game
(GameComponent
instead?). There should be only one Game
object.
You should replace you booleans and complex logic with Vector2 speed
describing speed of a ball, and negate its X or Y when the ball hits something.
Upvotes: 1