0

So I'm trying to create a pong game using monogame and im having some issue with my hit detection. I want the ball to switch directions when it hits the left padddle but for some reason the collision only gets detected on the top, not the sides so the ball just goes through the sides of the paddle but bounces when it hits the top can anyone see what am i doing wrong? Heres my code

Part of The Bat Class

public class Bat : DrawableGameComponent
{
    private SpriteBatch spriteBatch;
    private Texture2D tex;
    private Vector2 speed;
    private Vector2 position;
    private Vector2 stage;
    public Rectangle Rectangle
    {
        get
        {
            return new Rectangle((int)position.X, (int)position.Y, tex.Width, tex.Height);
        }
    }

    public Bat(Game game,
        SpriteBatch spriteBatch,
        Texture2D tex,
        Vector2 position,
        Vector2 speed,
        Vector2 stage): base(game)
    {
        this.spriteBatch = spriteBatch;
        this.tex = tex;
        this.position = position;
        this.speed = speed;
        this.stage = stage;
    }

The Collision classes update method

public override void Update(GameTime gameTime)
{
    if (ball.Rectangle.Intersects(bat.Rectangle))
    {
  
        ball.speed.Y = -Math.Abs(ball.speed.Y);
        hitSound.Play();
    }

    base.Update(gameTime);
}

And the game class that adds the bat and collision detection

Texture2D batTex = this.Content.Load<Texture2D>("Images/BatLeft");
Vector2 batPos = new Vector2(100,100);
Vector2 batSpeed = new Vector2(4, 0);
bat = new Bat(this, spriteBatch, batTex, batPos, batSpeed, stage);
this.Components.Add(bat);

SoundEffect dingSound = this.Content.Load<SoundEffect>("Music/ding");

CollisionDetection cd = new CollisionDetection(this, ball, bat, dingSound);
this.Components.Add(cd);
2
  • from the looks of it, the rectangle of the bat and the ball are not defined (you're using the Rectangle class instead of an unique variable), try using the rectangle as a standard variable without the get method. and call it from the public variable right away. Commented Dec 12, 2017 at 13:19
  • also you need circle-rectangle collision here. Commented Dec 13, 2017 at 7:58

1 Answer 1

0

Whenever the ball's rectangle intersects the paddle's rectangle you are reversing the direction of the ball's velocity. This method works fine when colliding only with the top or bottom of an object.

Whenever your ball collides with the top of the paddle, it's rectangle penetrates the paddle's rectangle. By reversing the ball's current downward speed to upward speed, you are able to remove the ball's rectangle completely from the paddle's rectangle.

Whenever your ball collide with the sides, the ball's speed changes from
{0, ballspeed}
to
{0, -ballSpeed}
This most likely is not enough to free the ball's rectangle from the paddle's rectangle. And if it is not free from the rectangle, the next update will reverse the direction again, thus canceling out the previous update. The ball will continue staying stuck in the rectangle until the paddle moves.

To Fix your problem, you should check whether the ball impacted the top, side, or bottom of the paddle. Then, adjust the ball's motion accordingly.

To get you started here is an example of one of my old collision detection methods:

// Moves and checks for collision on the Y-axis

position.Y += ball.speed.Y;
if (Hitbox().Intersects(obstacle))
{
    position.Y -= ball.speed.Y;
    ball.speed.Y = -ball.speed.Y;
}

// Moves and checks for collision on the X-axis

position.X += ball.speed.X;
if (Hitbox().Intersects(obstacle))
{
    position.X -= ball.speed.X;
    ball.speed.X = -ball.speed.X;
}

Hope I could help. If you have any questions about my explanation or code, feel free to ask.

-GHC

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.