I have to make pong for a school assignment. Everything was going pretty well
until I came to the collision part. Can somebody maybe help me?
I am doing it in visual studios c#, and I am a beginner, so I don't understand a lot. I have tried a lot of different solutions, but none of them seems to have worked out.
public override void GameStart()
{
}
public override void GameEnd()
{
}
public override void Update()
{
float DeltaTime = GAME_ENGINE.GetDeltaTime();
//Frame Rate Unlock
if (GAME_ENGINE.GetKeyDown(Key.V))
{
bool isLocked = GAME_ENGINE.GetVSync();
GAME_ENGINE.SetVSync(!isLocked);
}
//Player 1 Movement
if (GAME_ENGINE.GetKey(Key.W) && m_PlayerY1 != 0)
{
m_PlayerY1 -= 250 * DeltaTime;
}
if (GAME_ENGINE.GetKey(Key.S) && m_PlayerY1 != 300)
{
m_PlayerY1 += 250 * DeltaTime;
}
if (m_PlayerY1 < 0)
{
m_PlayerY1 = 0;
}
if (m_PlayerY1 > 350)
{
m_PlayerY1 = 350;
}
//Player 2
if (GAME_ENGINE.GetKey(Key.Up) && m_PlayerY2 != 0)
{
m_PlayerY2 -= 250 * DeltaTime;
}
if (GAME_ENGINE.GetKey(Key.Down) && m_PlayerY2 != 300)
{
m_PlayerY2 += 250 * DeltaTime;
}
if (m_PlayerY2 < 0)
{
m_PlayerY2 = 0;
}
if (m_PlayerY2 > 350)
{
m_PlayerY2 = 350;
}
//Ball Stuff
Random RnD = new Random();
m_XBallSpeed = RnD.Next(2, 3);
m_YBallSpeed = RnD.Next(2, 3);
m_XBall += m_XBallSpeed;
if (m_XBall < 0)
{
m_XBallSpeed = -m_XBallSpeed;
}
else if (m_XBall + m_BallWidth > GAME_ENGINE.GetScreenWidth())
{
m_XBallSpeed = -m_XBallSpeed;
}
m_YBall += m_YBallSpeed;
if (m_YBall < 0)
{
m_YBallSpeed = -m_YBallSpeed;
}
else if (m_YBall + m_BallHeight > GAME_ENGINE.GetScreenHeight())
{
m_YBallSpeed = -m_YBallSpeed;
}
if (m_XBall >= m_PlayerHeight1 && m_YBall >= m_PlayerHeight2)
{
m_XBallSpeed += 1;
m_YBallSpeed += 1;
m_XBallSpeed = -m_YBallSpeed;
}
if (m_YBall >= m_PlayerWidth1 && m_YBall >= m_PlayerWidth2)
{
m_XBallSpeed += 1;
m_YBallSpeed += 1;
m_XBallSpeed = -m_YBallSpeed;
}
}
public override void Paint()
{
//Player 1 and 2 and Ball
GAME_ENGINE.SetColor(255, 255, 255);
GAME_ENGINE.FillRectangle(m_PlayerX1, m_PlayerY1, m_PlayerWidth1, m_PlayerHeight1);
GAME_ENGINE.FillRectangle(m_PlayerX2, m_PlayerY2, m_PlayerWidth2, m_PlayerHeight2);
GAME_ENGINE.FillRoundedRectangle(m_XBall, m_YBall, m_BallWidth, m_BallHeight, 50, 50);
}
Related
Goal: The agent need to shoot red dots.
The agent shoots a ball that when it hits a red dot, it removes the dot and himself but when it hits an obstacle, only the ball disappear. (There's no bounce)
Example Level 1
The agent on the first level does really good, the problem is when i train on the other levels.
Example Level 2
Example Level 3 (Obstacles are moving left and right)
The agent does some success but after many episodes it gets stuck on loop, going left and right.
public class Capsule_ML : Agent
{
public GameObject sfera;
private int num, num_rossi; //tiri, numero rossi
public bool activate_shoot = false;
public Text num_sfere, punteggio, tempo_Rimanente;
//private float time_Left;
//private bool timer_Active;
public override void OnEpisodeBegin()
{
Episode_Debug.Episode += 1;
this.transform.rotation = Quaternion.Euler(Vector3.zero);
activate_shoot = false;
//timer_Active = true;
//time_Left = 60;
Active(this.transform.parent);
SearchRossiInParent(this.transform.parent);
punteggio.text = "#ROSSI: " + num_rossi;
num_sfere.text = "#SFERE: " + num;
}
//private void Update()
//{
// if (timer_Active)
// {
// time_Left -= Time.deltaTime;
// tempo_Rimanente.text = "Tempo Rimanente: " + time_Left + "s";
// if (time_Left <= 0)
// {
// timer_Active = false;
// TimeError();
// }
// }
//}
public void TimeError()
{
AddReward(-1.0f);
Episode_Debug.Fail += 1;
EndEpisode();
}
public override void CollectObservations(VectorSensor sensor)
{
}
public override void OnActionReceived(float[] action)
{
this.transform.Rotate(Vector3.back * action[0] * 60 * Time.deltaTime);
this.transform.Rotate(-Vector3.back * action[1] * 60 * Time.deltaTime);
if(UnityEditor.TransformUtils.GetInspectorRotation(this.transform).z < -90 || UnityEditor.TransformUtils.GetInspectorRotation(this.transform).z > 90)
{
AddReward(-1.0f);
Episode_Debug.Fail += 1;
EndEpisode();
}
RaycastHit2D hit = Physics2D.Raycast(this.transform.position, transform.TransformDirection(Vector3.down), Mathf.Infinity);
if (activate_shoot == false && hit.collider.tag == "red")
{
Debug.Log("Raycast colpisce " + hit.collider.name);
activate_shoot = true;
Debug.Log(activate_shoot);
Shoot();
//AddReward(1.0f);
}
//if (activate_shoot == false && action[2] == 1)
//{
// activate_shoot = true;
// Shoot();
//}
if ((num_rossi == 0 && num == 0) || (num_rossi == 0 && num > 0))
{
Episode_Debug.Success += 1;
AddReward(1.0f);
EndEpisode();
}
//if (num_rossi > 0 && num == 0)
//{
// Episode_Debug.Fail += 1;
// AddReward(-0.3f);
// EndEpisode();
//}
if (num < num_rossi)
{
Episode_Debug.Fail += 1;
AddReward(-1.0f);
EndEpisode();
}
Episode_Debug.ScreenText();
}
public void Shoot()
{
if (num > 0)
{
num -= 1;
num_sfere.text = "#SFERE: " + num;
GameObject clone = GameObject.Instantiate(sfera);
clone.transform.position = transform.position - transform.up * 1.0f;
clone.GetComponent<Rigidbody2D>().AddForce(-transform.up * 15.0f, ForceMode2D.Impulse);
}
}
public int GetCountRossi() //Numero Rossi Text
{
return num_rossi;
}
public void SetCountRossi(int x) //Numero Rossi Text
{
num_rossi = x;
}
//public void Shoot_Rosso() //check rosso colpito
//{
// AddReward(0.5f);
//}
public void Shoot_Error()
{
AddReward(-0.5f);
}
public void SearchRossiInParent(Transform parent) //Numero rossi iniziali nel livello e numero tiri
{
num_rossi = 0;
foreach(Transform red in parent)
{
if (red.gameObject.tag == "red")
num_rossi++;
}
num = num_rossi + 1;
}
public void Active(Transform parent)
{
foreach (Transform sphere in parent)
{
if (sphere.gameObject.tag == "red" || sphere.gameObject.tag == "blu")
sphere.gameObject.SetActive(true);
}
}
This is the code of the agent.
This is the .yaml config
behaviors:
Capsule_ML:
trainer_type: ppo
hyperparameters:
batch_size: 1024
buffer_size: 10240
learning_rate: 0.0004
beta: 0.005
epsilon: 0.2
lambd: 0.95
num_epoch: 5
learning_rate_schedule: linear
network_settings:
normalize: false
hidden_units: 128
num_layers: 2
vis_encode_type: simple
memory:
use_recurrent: true
sequence_length: 64
memory_size: 256
goal_conditioning_type: hyper
deterministic: false
reward_signals:
extrinsic:
gamma: 0.99
strength: 1.0
init_path: null
keep_checkpoints: 5
checkpoint_interval: 500000
max_steps: 500000
time_horizon: 64
summary_freq: 50000
threaded: false
self_play: null
behavioral_cloning: null
env_settings:
env_path: null
env_args: null
base_port: 5005
num_envs: 1
seed: -1
engine_settings:
width: 84
height: 84
quality_level: 5
time_scale: 20
target_frame_rate: -1
capture_frame_rate: 60
no_graphics: false
environment_parameters: null
checkpoint_settings:
run_id: TL1.1
initialize_from: null
load_model: false
resume: false
force: false
train_model: false
inference: false
debug: false
I'm using the RayPerception with these settings:
Settings
Tried to use a timer to end the episodes that gets stuck, but the agent is always in loop, even after many and many steps
I've been working on a project for the GMTK 2022 Game Jam recently, and I ran into a very strange problem. I have a dash that starts when you are moving and press space. It moves you in the direction of your velocity, then for a short time lets you move very quickly. It works perfectly fine in all cases, unless the direction you are moving is up and to the left, in which case, the if statement strangely won't trigger. I'm sure this is something idiotic, but I've been troubleshooting it for the last hour and it's been driving me insane.
// Update is called once per frame
void Update()
{
playerInputh = 0;
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
if (Input.GetKey("up"))
{
playerInputv = 1;
}
if (Input.GetKey("down"))
{
playerInputv = -1;
}
if (Input.GetKey("up") && Input.GetKey("down"))
{
playerInputv = 0;
}
Vector2 screenPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
Vector2 mouseWorldPosition = Camera.main.ScreenToWorldPoint(screenPosition);
//This is the dash that isn't working:
if ((Input.GetKeyDown(/*"right shift"*/"space")) && (playerInputh != 0 || playerInputv != 0))
{
Debug.Log("Dash");
//Vector2 transform2dposition = new Vector2(transform.position.x, transform.position.y);
m_Rigidbody.AddForce((m_Rigidbody.velocity) * 500f);
wJumpTimer = airControlAfterJump;
speed = maxSpeed*3.5f;
StartCoroutine(Roll());
}
}
void FixedUpdate()
{
//no moving while jumping!!!
if (wJumpTimer > 0)
{
wJumpTimer -= 1;
}
else
{
wJumpTimer = 0;
}
//move
if (playerInputh != 0 && playerInputv != 0) //make diagonals no super sayan
{
playerInputh *= moveLimiter;
playerInputv *= moveLimiter;
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
if ((playerInputh != 0 || playerInputv != 0) && speed < maxSpeed) //are we hitting the move buttons??
{
speed += acceleration;//accelerate
one_h = playerInputh;//futureproof
one_v = playerInputv;
}
else
{
if (speed > 0f) //are we getting off the ride
{
speed -= deceleration; //decelerate
}
else
{
speed = 0f; //no funny buisness
}
}
m_Rigidbody.velocity = new Vector2(one_h * speed, one_v * speed); //actually move
}
void SetFace(int diceNumb)
{
rndr.sprite = sprites[diceNumb];
}
IEnumerator Roll()
{
Random diceNumb = new Random();
rndr.sprite = sprites[diceNumb.Next(0,5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
rndr.sprite = sprites[diceNumb.Next(0, 5)];
yield return new WaitForSeconds(0.125f);
var newValue = diceNumb.Next(0, 5);
FaceValue = newValue + 1;
rndr.sprite = sprites[newValue];
}
How are your inputs setup? I am suspecting you have one key bound to multiple actions, like one key is set up as primary for an action and alternate for another action.
Personally I'd also stop using the assignment operators and increment instead. Instead of
playerInputh = 0;
if (Input.GetKey("right"))
{
playerInputh = 1;
}
if (Input.GetKey("left"))
{
playerInputh = -1;
}
if (Input.GetKey("right") && Input.GetKey("left"))
{
playerInputh = 0;
}
you can do
playerInputv = 0;
if (Input.GetKey("right"))
{
playerInputh += 1;
}
if (Input.GetKey("left"))
{
playerInputh += -1;
}
Net result is the same here - if you push both keys the result sums to zero, but the code is easier to read (IMO).
When you check things for key bindings also check alternates for space, because that's another one of the triggers you need to dash.
I'm learning XNA right now and i'm pretty new to programming in general. I'm making a platformer now but when I walk into a platform from left or right I get teleported to the top of the platform. The collision is only working with the last platform added to the platform list.
This is in Game class:
LoadContent:
for (int i = 0; i < 3; i++)
{
platform0List.Add(new Platform0(new Vector2(70 + (i * 300), 400), platform0Texture));
}
Update:
protected override void Update(GameTime gameTime)
{
keyboard = Keyboard.GetState();
player.Update(keyboard, keyboardPrev, platform0List);
foreach (Platform0 platform in platform0List)
{
if (!Move_Free(player.position.X, player.position.Y + player.gravity, player.texture.Width, player.texture.Height, platform.rectangle) && player.gravity >= 0)
{
player.ground = true;
if (player.position.Y + player.texture.Height + player.gravity > platform.position.Y)
{
player.position.Y = platform.position.Y - player.texture.Height;
}
else if (player.position.Y + player.texture.Height + player.gravity < platform.position.Y)
{
player.gravity = platform.position.Y - player.texture.Height;
}
break;
}
else
{
player.ground = false;
}
}
if (keyboard.IsKeyDown(Keys.Escape)) this.Exit();
keyboardPrev = keyboard;
base.Update(gameTime);
}
This is my Move_Free method
public static bool Move_Free(float x, float y, int width, int height, Rectangle rectangle)
{
Rectangle rect = new Rectangle((int)x,(int)y,width,height);
if(rect.Intersects(rectangle))
{
return false;
}
else
{
return true;
}
}
This is in Player class
foreach (Platform0 platform in platform0List)
{
if (keyboard.IsKeyDown(Keys.Right) && Game1.Move_Free(position.X + 5, position.Y, texture.Width, texture.Height, platform.rectangle))
{
moveRight = true;
}
else if (keyboard.IsKeyDown(Keys.Right) && ((position.X + texture.Width - platform.position.X) * -1) > 0)
{
position.X += (position.X + texture.Width - platform.position.X) * -1;
}
else
{
moveRight = false;
}
if (keyboard.IsKeyDown(Keys.Left) && Game1.Move_Free(position.X - 5, position.Y, texture.Width, texture.Height, platform.rectangle))
{
moveLeft = true;
}
else if (keyboard.IsKeyDown(Keys.Left) && position.X - (platform.position.X + platform.texture.Width) > 0)
{
position.X -= position.X - (platform.position.X + platform.texture.Width);
}
else
{
moveLeft = false;
}
}
if (moveRight) position.X += 5;
if (moveLeft) position.X -= 5;
if (keyboard.IsKeyDown(Keys.Up) && ground)
{
gravity = -10;
ground = false;
}
if(ground)
{
gravity = 0;
}
else
{
gravity += 9.8f / 60f;
position.Y += gravity;
}
Each iteration of your forloop overwrites your moveLeft and moveRight variables.
Therefore, only the last platform values will remain.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I'm making a game (Breakout) and I have a question,
The question is how can I remove the barriers after they get hit by the ball?
Of course, the ball must be able to go through the track after that (like Breakout game in general)
the next question is that can I make the barriers in run time mode?
Thanks
private void timer1_Tick(object sender, EventArgs e)
{
ball.Top += step;
ball.Left += stepleft;
//board simulate collision
bool collisonX = ball.Location.X + ball.Width > board.Location.X && ball.Location.X < board.Location.X + board.Width;
bool collisonY = ball.Top + ball.Height == board.Location.Y || ball.Top + ball.Height - 1 == board.Location.Y;
//board2(button1) simulate collision
bool collisonX2 = ball.Location.X + ball.Width > board2.Location.X && ball.Location.X < board2.Location.X + board2.Width;
bool collisonY2 = ball.Top + ball.Height == board2.Location.Y || ball.Top + ball.Height - 1 == board2.Location.Y;
//Collision the ball with under buttons
bool collsionButtonY = ball.Top - ball.Height == board2.Location.Y || ball.Top - ball.Height == board2.Location.Y - 1;
//collision leftwall
bool leftWall = ball.Left == 0 || ball.Left == -1 || ball.Left == 1;
//collision rightwall
bool topWall = ball.Top == 0 || ball.Top == -1 || ball.Top == 1;
bool bottomWall = collisonX && collisonY;
bool toppWall = collisonX2 && collisonY2;
//collision
bool barrier = collisonX2 && collsionButtonY;
bool collisionLeft = ((ball.Location.Y + ball.Height >= board2.Location.Y) && (ball.Location.Y <= board2.Location.Y + board2.Height) && (ball.Location.X + ball.Width >= board2.Location.X) && (ball.Location.X <= board2.Location.X + board2.Height));
//rightwall
bool rightWall = ball.Left + ball.Width == this.ClientSize.Width || ball.Left + ball.Width == this.ClientSize.Width - 1;
// sidewall = collision rightwall or leftwall
bool sideWall = leftWall || rightWall;
//Check the ball hit the ground
bool check = ball.Top + ball.Height < this.ClientSize.Height;
//if topWall true,This means that the ball is hit to the topwall
if (topWall)
{
flagBottom = false;
flagTop = true;
if (stepleft > 0)
{
step = 2;
}
else if (stepleft < 0)
{
step = 2;
}
}
//if bottomWall true,This means that the ball is hit to the board
else if (bottomWall)
{
flagBottom = true;
flagTop = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if barrier true and flagbottom true,This means that the ball is hit to the board2(button1)
else if (barrier && flagBottom)
{
collisionLeft = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
//if toppWall true and flagTop true,This means that the ball is hit to The top button is hit
else if (toppWall && flagTop)
{
collisionLeft = false;
if (stepleft > 0)
{
step = step * -1;
}
else if (stepleft < 0)
{
step = step * -1;
}
}
else if (flagTop && collisionLeft)
{
barrier = false;
if (stepleft > 0)
{
stepleft = -2;
step = 2;
}
else if (stepleft < 0)
{
stepleft = 2;
step = 2;
}
}
else if (flagBottom && collisionLeft)
{
barrier = false;
if (stepleft > 0)
{
stepleft = -2;
step = -2;
}
else if (stepleft < 0)
{
stepleft = 2;
step = -2;
}
}
else if (sideWall)
{
//if leftwall true,This means that the ball is hit to the left side wall
if (leftWall)
{
if (flagTop)
{
stepleft = 2;
}
else if (flagBottom)
{
stepleft = 2;
}
}
//if rightWall true,This means that the ball is hit to the left side wall
else if (rightWall)
{
if (flagTop)
{
stepleft = -2;
}
else if (flagBottom)
{
stepleft = -2;
}
}
}
//check if ckeck==ture,this mean the ball is hit the ground
else if (!check)
{
timer1.Enabled = false;
}
}
private void board_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
MouseDownLocation = e.Location;
}
}
private void board_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
board.Left = e.X + board.Left - MouseDownLocation.X;
}
You need to learn use lists and proper use of classes.
For example :
public class GameObject{
public GameObject(int x, int y, int width, int height){
this.X = x;
this.Y = y;
this.Width = width;
this.Height = height;
}
int X;
int Y;
int Width;
int Height;
public bool DetectCollision(bool Ball){
//code to detect collision
}
}
Then in your main class, you can do thing like that.
List<GameObject> gameObjects = new List<GameObject>();
gameObjects.add(new GameObject(10,10,50,50));
gameObjects.add(new GameObject(20,10,20,50));
gameObjects.add(new GameObject(30,10,50,70));
gameObjects.add(new GameObject(40,10,90,50));
And to detect the collisions :
foreach (GameObject gameObject in gameObjects){
if (gameObject.DetectCollision(ball)){
//do something
}
}
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;
}
}
}
}
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.
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.