Bounding box player collision (2D)

Hey guys, i’m very rookie to programming, and i’ve been trying to figure out how collision works in monogame. Here is my code

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;

  namespace projeto
{
public partial class Game1 : Game
{
    private GraphicsDeviceManager _graphics;
    private SpriteBatch _spriteBatch;

    private Rectangle _boxA;

    private Rectangle _boxB;
    private bool _areColliding;
    private Texture2D _pixel;
    private KeyboardState _prevKeyboardState;
    private KeyboardState _curKeyboardState;


    public Game1()
    {
        _graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
    }

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        
        _boxA = new Rectangle(100, 100, 50, 50);
        _boxB = new Rectangle(200, 200, 50, 50);
        
        base.Initialize();
    }

    protected override void LoadContent()
    {
        _spriteBatch = new SpriteBatch(GraphicsDevice);

        // TODO: use this.Content to load your game content here
        _spriteBatch = new SpriteBatch(GraphicsDevice);

        //  Create the 1x1 pixel texture
        _pixel = new Texture2D(GraphicsDevice, 1, 1);
        _pixel.SetData<Color>(new Color[] { Color.White });
    }

    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        // TODO: Add your update logic here
        _prevKeyboardState = _curKeyboardState;
        _curKeyboardState = Keyboard.GetState();

        MoveBoxA();
        MoveBoxB();
indent preformatted text by 4 spaces
        //  Check if _boxA and _boxB are colliding.
        _areColliding = CollisionChecks.AABB(_boxA, _boxB);


        base.Update(gameTime);
    }
    private void MoveBoxA()
    {
        if (_curKeyboardState.IsKeyDown(Keys.W))
        {
            _boxA.Y--;
        }
        else if (_curKeyboardState.IsKeyDown(Keys.S))
        {
            _boxA.Y++;
        }

        if (_curKeyboardState.IsKeyDown(Keys.A))
        {
            _boxA.X--;
        }
        else if (_curKeyboardState.IsKeyDown(Keys.D))
        {
            _boxA.X++;
        }
    }
    private void MoveBoxB()
    {
        if (_curKeyboardState.IsKeyDown(Keys.Up))
        {
            _boxB.Y--;
        }
        else if (_curKeyboardState.IsKeyDown(Keys.Down))
        {
            _boxB.Y++;
        }

        if (_curKeyboardState.IsKeyDown(Keys.Left))
        {
            _boxB.X--;
        }
        else if (_curKeyboardState.IsKeyDown(Keys.Right))
        {
            _boxB.X++;
        }
    }


    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        //  Draw the bounding boxes as white rectangles.
        Color color = Color.White;

        //  If the bounding boxes are colliding, make them red instead.
        if (_areColliding)
        {
           
        }

        _spriteBatch.Begin();
        _spriteBatch.Draw(_pixel, _boxA, color);
        _spriteBatch.Draw(_pixel, _boxB, color);
        _spriteBatch.End();
        base.Draw(gameTime);

        base.Draw(gameTime);
        }
      }
    }

And my collision.cheks class:

  using Microsoft.Xna.Framework;


  namespace projeto
{
public partial class Game1
{
    public static class CollisionChecks
    {
        public static bool AABB(Rectangle boxA, Rectangle boxB)
        {
            return boxA.Left < boxB.Right &&
                    boxA.Right > boxB.Left &&
                    boxA.Top < boxB.Bottom &&
                    boxA.Bottom > boxB.Top;
         }
      }
   }
}

`

I’m not sure what to put at the “if are colliding” part, last time i tried “color=color.red” and of course both boxes were made red, so the code works perfectly. However, i want to make them impassable, sort of like two moving walls. Maybe they could slide to the side too. But i want them to not occupy the same space when they collide. Could someone help me?

You need to take a look at this:

1 Like

Off the top of my head, here’s a solution:

In your movement code, don’t just do X++. Create a Vector2 (or since you’re using ints, a Point; but you should really switch to floats). I usually call this variable velocity. Set velocity to {0,0} at the beginning of each frame. Then, if the Right key is down, velocity.X++; Up key is down, velocity.Y--; etc.

Change CollisionChecks.AABB() to make it return a Rectangle. Make Left the distance between boxA.Left and boxB.Right; make Right the distance between boxA.Right and boxB.Left; etc. Get this result in your movement function. Let’s say something like result = CollisionCheck.AABB(boxA, boxB).

If result.Left is a negative number, then make sure that velocity.X is greater than result.Left. If result.Right is a positive number, then make sure that velocity.X is less than result.Right.

Then finally, add velocity.X to boxA.X and velocity.Y to boxA.Y. Then do the same for boxB's movement code. (At this point, you could even make a single function that handles the movement code & just pass in the rectangles & a bool for moveRight, moveLeft, ...).

Hope this helps!

1 Like