creating rectangles for each side of an object?

I'm building a breakout type game and I'm having a little issue with collision detection. How should I create the rectangle(s), do I do one rectangle per block but then how do I detect which side has been hit, or do I do 4 rectangles for each side of the block and base an if statement around them.

I tried to create 4 rectangles per block, one for top, bottom etc etc but I couldn't get it correct. heres my code to see if you can work out the best way to handle it.

Brick class:

class Bricks
{
    Texture2D redbrickimg;
    Texture2D blueBrickimg;
    Texture2D greenBrickimg;
    Texture2D pinkBrickimg;
    Texture2D aquaBrickimg;

    /*Rectangle aquaBrickrectangle;
    Rectangle redBrickrectangle;
    Rectangle blueBrickrectangle;
    Rectangle greenBrickrectangle;
    Rectangle pinkBrickrectangle;
     */
    Rectangle[,] topHit = new Rectangle[12,12];
    Rectangle[,] bottomHit = new Rectangle[12,12];
    Rectangle[,] rightHit = new Rectangle[12,12];
    Rectangle[,] leftHit = new Rectangle[12,12];

    int[,] redBrickXPos = new int [12,12];
    int[,] redBrickYPos = new int [12,12];
    int[,] colourBrick  = new int[12, 12];

    public Bricks(
        Texture2D Redbricks,
        Texture2D blueBricks,
        Texture2D greenBricks,
        Texture2D pinkBricks,
        Texture2D aquaBricks
        )
    {
        redbrickimg  = Redbricks;
        blueBrickimg = blueBricks;
        greenBrickimg = greenBricks;
        pinkBrickimg = pinkBricks;
        aquaBrickimg = aquaBricks;
    }

    public void Initialize()
    {
        for (int j = 0; j < 12; j++)
        {

            for (int i = 0; i < 12; i++)
            {
                redBrickXPos[j,i] = 1 + i * redbrickimg.Width;
                redBrickYPos[j,i] = 1 + j * redbrickimg.Height;

                colourBrick[j,i] = j/2;
            }                
        }
    }

    public void Update()
    {
    }

    public void Draw(SpriteBatch spritebatch)
    {
        for (int j = 0; j < 12; j++)
        {
            for (int i = 0; i < 12; i++)
            {
                if (colourBrick[j, i] == 0)
                {
                    spritebatch.Draw(redbrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
                }
                else if (colourBrick[j, i] == 1)
                {
                    spritebatch.Draw(blueBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
                }
                else if (colourBrick[j, i] == 2)
                {
                    spritebatch.Draw(greenBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]), Color.White);
                }
                else if (colourBrick[j, i] == 3)
                {
                    spritebatch.Draw(pinkBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]),Color.White);
                }
                else if (colourBrick[j, i] == 4)
                {
                    spritebatch.Draw(aquaBrickimg, new Vector2(redBrickXPos[j, i], redBrickYPos[j, i]), Color.White);
                }
            }
        }
    }
}

My main class:

public class Breakout : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Texture2D BackgroundImg;
    Bricks bricks;
    Paddle paddle;
    GameBall gameball;
    bool iskeyLeft = false;
    bool iskeyRight = false;
    bool Flag;
    int moveBy;
    float ballX;
    float ballY;

    public Breakout()
    {
        graphics = new GraphicsDeviceManager(this);

        graphics.PreferredBackBufferWidth = 960;
        graphics.PreferredBackBufferHeight = 768;
        graphics.ApplyChanges();
        Content.RootDirectory = "Content";
    }

    protected override void Initialize()
    {
        base.Initialize();
        bricks.Initialize();
        paddle.Initialize();
        gameball.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);
        BackgroundImg = Content.Load<Texture2D>("starfield");
        bricks = new Bricks(
            Content.Load<Texture2D>("red brick"),
            Content.Load<Texture2D>("brickblue"),
            Content.Load<Texture2D>("greenbrick"),
            Content.Load<Texture2D>("pinkbrick"),
            Content.Load<Texture2D>("aquaBrick")
            );

        paddle = new Paddle(Content.Load<Texture2D>("Paddle"), 
            new Rectangle(0, 0, 110, 30),iskeyLeft,iskeyRight);

        gameball = new GameBall(Content.Load <Texture2D>("ball"), 
            new Rectangle(0, 0, 60, 60));

        IsMouseVisible = true;

        // TODO: use this.Content to load your game content here
    }

    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        // call update on paddle 

       moveBy =  paddle.Update();

       Flag = gameball.Update();
       if (Flag == false)
       {
           gameball.moveBall(moveBy);
       }

        // TODO: Add your update logic here
        // mainmenu = new mainmenu(mainmenuISon, Content.Load<Texture2D>("option_menu"),
        Content.Load<Texture2D>("start_button"), Content.Load<Texture2D>("exit_button"));

        base.Update(gameTime);
    }

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

        base.Draw(gameTime);
        spriteBatch.Begin();
        spriteBatch.Draw(BackgroundImg, Vector2.Zero, Color.White);
        bricks.Draw(spriteBatch);
        paddle.Draw(spriteBatch);
        gameball.Draw(spriteBatch);

        spriteBatch.End();
    }
}

Answers


You left out the most interesting part of your code where you're actually attempting the collision test.

I would go with one rect for your brick (and thereby only one collision test per brick) and only if that passes you need to figure out what side was hit. You can easily rule out two sides by the direction of the GameBall (you cannot hit the "backside"). For the remaining two sides you check if the "front" corner is on the left or right of your current line of movement.


Need Your Help

Mouseup not firing after mousedown in jQuery

javascript jquery

When I click, I get an alert saying "down" but not "up." I read that e.preventDefault() should fix the problem, but it hasn't. Does anyone have any suggestions?

Postgresql vs. MySQL: how do their data sizes compare to each other?

mysql postgresql storage data-storage

For the same data set, with mostly text data, how do the data (table + index) size of Postgresql compared to that of MySQL?