XNA Creators Club Online
Page 1 of 1 (8 items)
Sort Posts: Previous Next

Help wanted - Ball collisions in Brick Breaker

Last post 11/25/2009 5:51 PM by Altourus. 7 replies.
  • 5/4/2009 10:36 PM

    Help wanted - Ball collisions in Brick Breaker

    Hey! I'm currently working on an independent research project for school, and I'm doing C# and XNA. I've already had some experience in both of these, mostly C#. Graphics are no problem, and neither are menus, but for some reason I simply cannot get ball collisions right. The ball will bounce off the walls with no problem, but I cant get it to collide with the paddle and go in the opposite direction. Here is my current Game1() (Understandably, the code is messy. I'll clean it up with classes etc. towards the end):

    using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using Microsoft.Xna.Framework;  
    using Microsoft.Xna.Framework.Audio;  
    using Microsoft.Xna.Framework.Content;  
    using Microsoft.Xna.Framework.GamerServices;  
    using Microsoft.Xna.Framework.Graphics;  
    using Microsoft.Xna.Framework.Input;  
    using Microsoft.Xna.Framework.Media;  
    using Microsoft.Xna.Framework.Net;  
    using Microsoft.Xna.Framework.Storage;  
     
    namespace Testing  
    {  
        /// <summary>  
        /// This is the main type for your game  
        /// </summary>  
        public class Game1 : Microsoft.Xna.Framework.Game  
        {  
            GraphicsDeviceManager graphics;  
            SpriteBatch spriteBatch;  
     
     
     
            Texture2D paddletexture;  
            Vector2 paddleposition;  
            Vector2 paddlevelocity;  
            Rectangle playerrectangle;  
     
     
            Vector2 Leftside;  
            Vector2 Rightside;  
     
            Texture2D balltexture;  
            Vector2 ballposition;  
            Rectangle ballrectangle;  
            int ballxSpeed;  
            int ballySpeed;  
     
     
              
            Rectangle viewportrect;  
              
             
            SpriteFont Arial;  
              
     
            public Game1()  
            {  
                graphics = new GraphicsDeviceManager(this);  
                Content.RootDirectory = "Content";  
     
                graphics.PreferredBackBufferHeight = 500;  
                graphics.PreferredBackBufferWidth = 500;  
                graphics.ApplyChanges();  
            }  
     
            /// <summary>  
            /// Allows the game to perform any initialization it needs to before starting to run.  
            /// This is where it can query for any required services and load any non-graphic  
            /// related content.  Calling base.Initialize will enumerate through any components  
            /// and initialize them as well.  
            /// </summary>  
            protected override void Initialize()  
            {  
                // TODO: Add your initialization logic here  
                paddleposition = new Vector2(200, 470);  
               
     
                viewportrect = new Rectangle(graphics.GraphicsDevice.Viewport.Width,  
                    graphics.GraphicsDevice.Viewport.Height, 0, 0);  
     
                Leftside = new Vector2(2, 10);  
                Rightside = new Vector2(392, 10);  
     
                ballrectangle = new Rectangle((int)ballposition.X, (int)ballposition.Y,  
                   50, 50);  
     
                playerrectangle = new Rectangle((int)paddleposition.X, (int)paddleposition.Y,  
                    100, 100);  
                
                  
     
                
     
     
                  
     
                  
                  
     
                base.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);  
                paddletexture = Content.Load<Texture2D>("Paddle"as Texture2D;  
                balltexture = Content.Load<Texture2D>("Ball"as Texture2D;  
     
                Arial = Content.Load<SpriteFont>("Arial Black");  
     
                // TODO: use this.Content to load your game content here  
            }  
     
            /// <summary>  
            /// UnloadContent will be called once per game and is the place to unload  
            /// all content.  
            /// </summary>  
            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();  
     
                paddleposition += paddlevelocity;  
                  
     
                GamePadState gamePadstate = GamePad.GetState(PlayerIndex.One);  
     
     
     
                if (gamePadstate.IsButtonDown(Buttons.LeftThumbstickLeft)  
                   && paddleposition.X >= Leftside.X)  
                {  
                    paddlevelocity.X -= 5;  
                }  
                else 
                {  
                    paddlevelocity.X = 0;  
                }  
                  
                
                 if (paddleposition.X <= Leftside.X)  
                {  
                    paddlevelocity.X = 0;  
                }  
     
     
     
     
     
     
                 if (gamePadstate.IsButtonDown(Buttons.LeftThumbstickRight))  
                 {  
                     paddlevelocity.X += 5;  
                 }  
                 else 
                 {  
                     paddlevelocity.X = 0;  
                 }  
                 if (paddleposition.X >= Rightside.X)  
                 {  
                     paddlevelocity.X = 0;  
                 }  
     
                 if (gamePadstate.IsButtonDown(Buttons.LeftThumbstickLeft)  
                     && paddleposition.X >= Leftside.X)  
                 {  
                     paddlevelocity.X -= 5;  
                 }  
     
     
                 ballUpdate();  
     
                 if (ballposition.X + balltexture.Width> graphics.GraphicsDevice.Viewport.Width)  
                 {  
                     ballxSpeed *= -1;  
                 }  
     
                 else if (ballposition.X < 0)  
                 {  
                     ballxSpeed *= -1;  
                 }  
     
                 if (ballposition.Y + balltexture.Height> graphics.GraphicsDevice.Viewport.Height)  
                 {  
                     ballySpeed *= -1;  
                 }  
     
                 
     
                 playerrectangle.X = (int)paddleposition.X;  
                 playerrectangle.Y = (int)paddleposition.Y;  
                 ballrectangle.X = (int)ballposition.X;  
                 ballrectangle.Y = (int)ballposition.Y;  
     
                 if (ballrectangle.Intersects(ballrectangle))  
                 {  
                     ballposition.Y = playerrectangle.Top;  
                       
     
                     ballySpeed *= -1;  
                      
                 }  
                 ballUpdate();  
     
                   
     
                   
                // TODO: Add your update logic here  
     
                base.Update(gameTime);  
            }  
     
     
            void ballUpdate()  
            {  
                ballxSpeed = 4;  
                ballySpeed = 4;  
     
                ballposition.X += ballxSpeed;  
                ballposition.Y += ballySpeed;  
     
                 
     
     
               
            }  
            /// <summary>  
            /// This is called when the game should draw itself.  
            /// </summary>  
            /// <param name="gameTime">Provides a snapshot of timing values.</param>  
            protected override void Draw(GameTime gameTime)  
            {  
                GraphicsDevice.Clear(Color.CornflowerBlue);  
                spriteBatch.Begin();  
                spriteBatch.Draw(paddletexture, paddleposition, Color.White);  
                spriteBatch.Draw(balltexture, ballposition, Color.White);  
                spriteBatch.DrawString(Arial, "\nControls:\nLeft Trigger - Stop\nLeft Thumbstick - Move",  
                    new Vector2(0, graphics.GraphicsDevice.Viewport.Width / 2 + -5), Color.Green);  
     
                  
                spriteBatch.End();  
     
                // TODO: Add your drawing code here  
     
                base.Draw(gameTime);  
            }  
        }  
    }  
     

    Anyone have any ideas? All help is appreciated, except for pointless flaming/insult.

     

    Thanks

    -Jordin and Sean

  • 5/4/2009 10:53 PM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    Should this line:

     if (ballrectangle.Intersects(ballrectangle))  

    be this:

     if (ballrectangle.Intersects(playerrectangle))  
    Jim Perry - Microsoft XNA MVP
    If people spent a minute searching the forums and reading the FAQs before posting I'd be out of a job.
      Got some XNA Game Studio/XNA Framework development info to share with the community? Put it on the XNA Wiki.
        Please mark posts as Answers or Good Feedback when appropriate.
  • 5/5/2009 6:35 AM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    Yikes, yes it should! Thanks for pointing out our idiocy! However, the problem hasnt been fixed even after that error was. The ball hits the paddle, then seems to simply give up on its y axis and moves horizontally along the paddle's x position (out of the screen). Any other ideas?

    -Thanks
    Jordin and Sean
  • 5/5/2009 6:40 AM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    The BallUpdate() method looks suspect because you are reversing the ballyspeed when intercepting the paddle, but then you are calling BallUpdate which promptly resets ballyspeed to 4 which cancels out any previous change.
    Game hobbyist hell-bent on coding a diabolical Matrix
  • 5/5/2009 7:13 AM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    Alrighty then. Thanks for the suggestion, I see what you mean, and I'll give an idea you gave me a try and post my results tomorrow morning.  If it fixes the problem, I'll edit my main post showing the resolution. Thanks to the two of you who have contributed thus far, I speak for the both of us when I say we GREATLY appreciate the help!

    -Jordin and Sean
  • 5/13/2009 10:20 PM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    I wrote some similar code in my pong game and randomly got strange results. You're reversing the balls speed in *every frame* that the sprites intersect. This means if your ball intersected for multiple frames (maybe due to rounding/floating point inaccuracies) it will reverse multiple times. You might see the ball get "stuck" to your paddle.

    I found the best thing to do is check the direction of the ball and only reverse it if it's heading towards the paddle.
  • 5/13/2009 10:29 PM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    http://www.krissteele.net/blogdetails.aspx?id=141

    Here is a blog post I wrote about doing exactly this sort of thing, take a look and see if it helps you out.
  • 11/25/2009 5:51 PM In reply to

    Re: Help wanted - Ball collisions in Brick Breaker

    Recently did a Pong game, http://nickcrook.ca/Pong/Publish.htm You can take a look at the source code at http://nickcrook.ca/Pong/PongSourceCode.zip
    While the commenting is lacking and the code not the cleanest. If you look in /GameObjects/Ball.cs you should find all the bounce functionality for the paddles your looking for. Things to note, the ball will properly check for collisions even at velocities so fast they would normally pass through the paddle, and will end up where they should, even if bouncing off multiple surfaces in a single update. The paddles will cause balls to bounce off at angles relative to the angle they hit at and where they hit the paddle. The calculations assume the paddle and the walls are vertical or horizontal, not diagonal. Lastly, dont trust the computer player... hes evil :'(
Page 1 of 1 (8 items) Previous Next