# C# XNA Framework Paddle Collision Problems

I am trying to make a pong game that uses a burger as a ball and a plate as its paddle. I have everything right except that the burger goes right through the plate. Can anyone help me?

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;

namespace Burger_Attack_Mitch_McCauley
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GameSprite myGameSprite;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;

Texture2D imageBurger;
Texture2D imagePlate;
Texture2D imageStart;
Texture2D imageEnd;

KeyboardState keyState_01;
KeyboardState keyState_01_Old;

int intGameState;

GameSprite spriteStartScreen_01;
GameSprite spriteEndScreen_01;
GameSprite spritePlate;
GameSprite spriteBurger;

public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}

/// <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()
{

myGameSprite = new GameSprite();

spriteStartScreen_01 = new GameSprite();
spriteEndScreen_01 = new GameSprite();
spritePlate = new GameSprite(300, 425, 150, 50);
spriteBurger = new GameSprite(300, 300, 150, 100, 1, -1);

intGameState = 5;

base.Initialize();
}

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// </summary>
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

spriteStartScreen_01.spriteTexture = imageStart;
spriteEndScreen_01.spriteTexture = imageEnd;
spriteBurger.spriteTexture = imageBurger;
spritePlate.spriteTexture = imagePlate;

}

/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
{
// 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
this.Exit();

GetUserInput();
ChangeGameState();

switch (intGameState)
{
case 5:
break;

case 86:
break;
default:
MoveUserControlledSprites();
MoveSprites();
TestForCollisions();
break;
}

base.Update(gameTime);
}

/// <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();

switch (intGameState)
{
case 5:
spriteBatch.Draw(spriteStartScreen_01.spriteTexture,
spriteStartScreen_01.spritePos, Color.White);
break;

case 86:
spriteBatch.Draw(spriteEndScreen_01.spriteTexture,
spriteEndScreen_01.spritePos, Color.White);
break;
default:

spriteBatch.Draw(spriteBurger.spriteTexture,
spriteBurger.spritePos, Color.White);
spriteBatch.Draw(spritePlate.spriteTexture,
spritePlate.spritePos, Color.White);
break;
}
spriteBatch.End();

base.Draw(gameTime);
}
private void GetUserInput()
{
keyState_01_Old = keyState_01;

keyState_01 = Keyboard.GetState();
}

private void ChangeGameState()
{if (intGameState == 5 &&
{
intGameState = 10;
}
if (intGameState == 5 &&
keyState_01.IsKeyDown (Keys.Space) &&
keyState_01_Old.IsKeyUp(Keys.Space))
{
intGameState = 10;
}

if (intGameState == 86 &&
{
intGameState = 5;
spriteBurger.spritePos.X = 300;
spriteBurger.spritePos.Y = 0;
}

if (intGameState == 86 &&
keyState_01.IsKeyDown(Keys.Space) &&
keyState_01_Old.IsKeyUp(Keys.Space))
{
intGameState = 5;
spriteBurger.spritePos.X = 300;
spriteBurger.spritePos.Y = 0;
}
}
private void MoveSprites()
{
if (spriteBurger.spritePos.X <= 0)
{
spriteBurger.spriteSpeed.X = 2;
}
if (spriteBurger.spriteSpeed.Y <= 0)
{
spriteBurger.spriteSpeed.Y = 2;
}
if (spriteBurger.spritePos.X +
spriteBurger.spriteDims.X >=
Window.ClientBounds.Width)
{
spriteBurger.spriteSpeed.X = -2;
}
if (spriteBurger.spritePos.Y +
spriteBurger.spriteDims.Y >+
Window.ClientBounds.Height)
{
intGameState = 86;
}
spriteBurger.spritePos.X += spriteBurger.spriteSpeed.X;
spriteBurger.spritePos.Y += spriteBurger.spriteSpeed.Y;
}
private void MoveUserControlledSprites()
{
if (keyState_01.IsKeyDown(Keys.Left))
{
spritePlate.spritePos.X -= 3;
}
if (keyState_01.IsKeyDown(Keys.Right))
{
spritePlate.spritePos.X += 3;
}

if (spritePlate.spritePos.X < 0)
{
spritePlate.spritePos.X = 0;
}

if (Window.ClientBounds.Width < (spritePlate.spritePos.X + spritePlate.spriteDims.X))
{
spritePlate.spritePos.X = (Window.ClientBounds.Width - spritePlate.spriteDims.X);
}
}

private void TestForCollisions()
{
Rectangle plateRect = new Rectangle(
(int)spritePlate.spritePos.X,
(int)spritePlate.spritePos.Y,
(int)spritePlate.spriteDims.X,
(int)spritePlate.spriteDims.Y);

Rectangle burgerRect = new Rectangle(
(int)spriteBurger.spritePos.X,
(int)spriteBurger.spritePos.Y,
(int)spriteBurger.spriteDims.X,
(int)spriteBurger.spriteDims.Y);

if (plateRect.Intersects(burgerRect))
{
spriteBurger.spriteSpeed.Y = -1 *
Math.Abs(spriteBurger.spriteSpeed.Y);
}
}

}

}

• Welcome to GameDev.StackExchange, Mitch! This isn't really a place to post all of your code and ask someone to fix it. In this case, you should be posting only the code relevant to handling collisions. This will make it much easier for people to look at what the problem might be, without having to sift through your whole code base. Which also improves the chances of people actually taking the time to look at it and give you an answer. Please consider revising your question so that only the relevant code is shown. Also, there's a button at the top of the post page: {}. It will format your code. – Richard Marskell - Drackir Aug 5 '11 at 2:13
• Please use the debugger and post what you find out. – Maik Semder Aug 5 '11 at 5:59

Mitch, you're going to run into a lot of similar problems on your way to the finished game. It's often pointless to ask others to debug your code, especially when it's not so hard to do it yourself. Like they say, “Teach a man to fish; and you will not have to listen to his questions about debugging basics”, so lets do a debugging 101:

You say that a ball goes right trough a paddle. A simple assumption can be made that either collision check via rectangle bounds or reaction to the ball after collision is wrong. Lets see if its one of these cases:

1. Place a breakpoint in the body of condition if (plateRect.Intersects(burgerRect)) {...} and see if it hits.
2. If it does hit, collision is working and your modification of ball's coordinates does not work.
3. If it doesn't hit, collision is not working. Place a breakpoint after creation of your two bounding rectangles and check their properties, especially this spriteDims thingies.
4. If everything is seemingly fine, look at your sources again, check every coordinate assignment, breakpoint every line if you have to, and sooner or later you will catch a bug :)

Further down the development process you will probably want to increase difficulty over time by increasing your ball's speed, and at one point it may start going through paddle again :)

When collisions are done with a naive collision check and assignments like spritePos.Y += spriteSpeed.Y, your ball can go right through paddle even if everything is seemingly right; e.g. if a ball's position is increased by a number which is larger than a paddle's bounding rectangle dimension. You may want to google "collision detection", there are a lot of good things to read.

• When debugging this I found that the paddle was actually the wrong size, so instead of going straight through the paddle, I would have to move it farther to the right in order to bounce the ball back. – Mitch Aug 5 '11 at 11:13
• Congratulations :) You may want to start placing simple asserts in your code, like when you expect a paddle to have a specific width after some function calls, back up your expectation with a Debug.Assert, it may save you a lot of time in the long run. – EnoughTea Aug 5 '11 at 12:20

When your spriteBurger.spriteSpeed is set to -2 (when it's moving upwards I'm guessing) the following line of code you have won't have any effect:

spriteBurger.spriteSpeed.Y = -1 * Math.Abs(spriteBurger.spriteSpeed.Y);


This is because you're essentially saying -1 * 2 which equals -2, which is where you started.

You can simply use the following code to reverse the direction your spriteBurger is going:

spriteBurger.spriteSpeed.Y = -spriteBurger.spriteSpeed.Y;


Based on looking at the code above though, I don't think spriteBurger.spriteSpeed.Y is ever set to -2 so I'm not sure what the change above will do for you.

• What I am aiming for is the fact that the plate (The paddle of the pong game) does not work, the ball (Burger) goes right through it. I want to know where I messed up in all of that. That is the reason I posted all of the code. – Mitch Aug 5 '11 at 6:27