--- Finished Breakout ---

Started by
13 comments, last by jbadams 11 years, 5 months ago
I finsihed my breakout project. I feel like things are coming together, my next step is going to snake. I feel like am making some right moves, I am really starting like programming.

MisterVirtue's Breakout Game

Tell me what you think.
Advertisement
I fixed the link sorry about that.
Why don't you just paste the code here? It's far more likely that somebody will take a look at it.
Really? You need the source code to try out a game...?

Beginner in Game Development?  Read here. And read here.

 

I have no intention of playing it (and the OP did not specifically ask for that), I want to look at the code and critique that.

I'm also not in the habit of downloading and running random executable from forums anyhow, especially this one. It only takes one such instance for us to have a repeat of fongerchat.
Sure, Posting the source code wouldn't hurt.
Source Code HOOOOO!

Sprite Manager / Game Compentent
[source lang="csharp"]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 Jreakout_BreakOutClone_
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent
{
SpriteBatch spriteBatch;

PlayerPaddle playerPaddle;
Rectangle screenRectangle;
Ball ball;

//Columns and rows for brick
int bricksWide = 10;
int bricksHigh = 5;
//Texture for the brick
Texture2D brickImage;
//Array for the placement for the bricks
Brick[,] bricks;

public SpriteManager(Game game)
: base(game)
{
// TODO: Construct any child components here
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(Game.GraphicsDevice);
screenRectangle = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height);
Texture2D playerPaddleTexture = Game.Content.Load<Texture2D>("paddle");
playerPaddle = new PlayerPaddle(playerPaddleTexture, screenRectangle);
Texture2D ballTexture = Game.Content.Load<Texture2D>("ball");
ball = new Ball(ballTexture, screenRectangle);

brickImage = Game.Content.Load<Texture2D>("brick");

StartGame();
base.LoadContent();
}


/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here

base.Initialize();
}

/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
playerPaddle.Update();
ball.Update();

//Check For Collisions
ball.CheckForWallCollision();
ball.CheckForPlayerCollision(playerPaddle.GetBounds());

foreach (Brick brick in bricks)
{
brick.CheckCollision(ball);
}

if (ball.CheckForBottom())
{
StartGame();
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();

foreach (Brick brick in bricks)
{
brick.Draw(spriteBatch);
}

ball.Draw(spriteBatch);
playerPaddle.Draw(spriteBatch);
spriteBatch.End();

base.Draw(gameTime);
}
public void StartGame()
{
playerPaddle.SetInStartPosition();
ball.SetInStartPosition();

//When the game starts Place the bricks
//Layer them by color

//Create an array to hold the bricks
bricks = new Brick[bricksWide, bricksHigh];
//Loop thr
for (int y = 0; y < bricksHigh; y++)
{
Color tint = Color.White;
switch (y)
{
case 0:
tint = Color.Blue;
break;
case 1:
tint = Color.Red;
break;
case 2:
tint = Color.Green;
break;
case 3:
tint = Color.Yellow;
break;
case 4:
tint = Color.Purple;
break;
}
for (int x = 0; x < bricksWide; x++)
{
bricks[x, y] = new Brick(
brickImage, new Rectangle(
x * brickImage.Width, y * brickImage.Height,
brickImage.Width, brickImage.Height), tint);
}
}
}
}
}[/source]
Brick Class
[source lang="csharp"]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

namespace Jreakout_BreakOutClone_
{
class Brick
{
//Holds the texture for the brick
Texture2D texture;
//Holds the position of the brick
Vector2 position;
//Holds the location of the brick
Rectangle location;
//Allows to change the color of the bricks
Color tint;
//A boolean value to see if the brick is alive or not.
bool alive;

public Rectangle Location
{
get { return location; }
}
//Constructor for the brick class
public Brick(Texture2D texture, Rectangle location, Color tint)
{
this.texture = texture;
this.location = location;
this.tint = tint;
this.alive = true;
}
//Check to see if anything has collided with the brick
public void CheckCollision(Ball ball)
{
if (alive && ball.Bounds.Intersects(location))
{
alive = false;
ball.Deflection(this);
}
}
public void Draw(SpriteBatch spriteBatch)
{
if (alive)
{
spriteBatch.Draw(texture,location,tint);
}
}
}
}
[/source]
Ball Class
[source lang="csharp"]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

namespace Jreakout_BreakOutClone_
{
class Ball
{
//Holds for the direction the ball is travelling
Vector2 motion;
//Holds for the the current position of the ball
Vector2 position;
//Holds for the speed of the ball
float ballSpeed = 5;

//Holds for the texture Image of ball;
Texture2D texture;

//Holds for the bounds of the screen
Rectangle screenBounds;

//Rectangle Bounds
Rectangle bounds;

public Rectangle Bounds
{
get
{
bounds.X = (int)position.X;
bounds.Y = (int)position.Y;
return bounds;
}
}

//Consturtor for the ball class
//This allows for the creation of instances of ball. Pass texture and screenbounds as parameters
public Ball(Texture2D texture, Rectangle screenBounds)
{
this.texture = texture;
this.screenBounds = screenBounds;
}
//Upate for the ball class
//Check for Ccollisions with the wall and the player
public void Update()
{
position += motion * ballSpeed;
CheckForWallCollision();
}
//Check to see if the ball is hitting the window bounds on the left and right and top
//Reverse it's direction upon collision
public void CheckForWallCollision()
{
//Top of the Screen
if (position.Y < 0)
{
position.Y = 0;
motion.Y *= -1;
}
//Left Bound
if (position.X < 0)
{
position.X = 0;
motion.X *= -1;
}
//Right Bound
if (position.X + texture.Width > screenBounds.Width)
{
position.X = screenBounds.Width - texture.Width;
motion.X *= -1;
}
}
//Check to see if the ball is hitting the player paddle
//Reverese it's direction upon collision
public void CheckForPlayerCollision(Rectangle paddleLocation)
{
Rectangle ballLocation = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height);
if (paddleLocation.Intersects(ballLocation))
{
position.Y = paddleLocation.Y - texture.Height;
motion.Y = -1;
}
}
//Check to see if the ball has gone of the bottom of the screen
//If so return true
public bool CheckForBottom()
{
if (position.Y + texture.Height > screenBounds.Height)
{
return true;
}
return false;
}
public void SetInStartPosition()
{
motion = new Vector2(-1,1);
position.X = (screenBounds.Width - texture.Width) / 2;
position.Y = (screenBounds.Height - texture.Height) / 2;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
public void Deflection(Brick brick)
{
motion.Y *= -1;
}
}
}[/source]

Game1.cs

[source lang="csharp"]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 Jreakout_BreakOutClone_
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SpriteManager spriteManager;
Rectangle screenRectangle;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 600 ;
graphics.PreferredBackBufferWidth = 750;
screenRectangle = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);

}

/// <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()
{
//Instantiate the spriteManager
spriteManager = new SpriteManager(this);
Components.Add(spriteManager);

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

// 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(Keyboard.GetState().IsKeyDown(Keys.Escape))
{
this.Exit();
}

// TODO: Add your update logic here

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

// TODO: Add your drawing code here

base.Draw(gameTime);
}
}
}[/source]

PlayerPaddle Class
[source lang="csharp"]using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Media;

namespace Jreakout_BreakOutClone_
{
class PlayerPaddle
{
//Variable Declaration//

//Holds the Position of the PlayerPaddle
Vector2 position;

//Holds the Direction the PlayerPaddle is move
Vector2 direction;

//Holds the speed of the player paddle
float paddleSpeed =8;

//Holds the texture Image for the ball
Texture2D texture;

//Allow for player Input
KeyboardState keyboardState;

//Holds the Rectangle for the GameWindow
Rectangle screenBounds;

//End of Variable Declaration//

//Consturctor for the PlayerPaddle
// Used to create an instance of PlayerPaddle (Pass texture,screenbounds as parameters)
public PlayerPaddle(Texture2D texture, Rectangle screenBounds)
{
this.texture = texture;
this.screenBounds = screenBounds;
}

//Update for Paddle
//Use Keyboard to allow for Movment only in the X direction
public void Update()
{
direction = Vector2.Zero;
keyboardState = Keyboard.GetState();
if(keyboardState.IsKeyDown(Keys.Left))
{
direction.X = -1;
}
if (keyboardState.IsKeyDown(Keys.Right))
{
direction.X = 1;
}
direction.X *= paddleSpeed;
position += direction;
CheckScreenBounds();
}

//Draw for Paddle
//Draw the Paddle Yellow
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.Purple);
}
//CheckScreenBounds for PlayerPaddle
//Do not Allow the Paddle to leave the clientBounds
public void CheckScreenBounds()
{
if (position.X < 0)
{
position.X = 0;
}
if (position.X + texture.Width > screenBounds.Width)
{
position.X = screenBounds.Width - texture.Width;
}
}
//GetBounds for PlayerPaddle
//Create A Rectangle around the texture image of playerPaddle
public Rectangle GetBounds()
{
return new Rectangle
((int)position.X, (int)position.Y, texture.Width, texture.Height);
}
public void SetInStartPosition()
{
position.X = (screenBounds.Width - texture.Width) / 2;
position.Y = screenBounds.Height - texture.Height - 5;
}

}
}
[/source]

There you go.


I'm also not in the habit of downloading and running random executable from forums anyhow.


Probably a smart habit.

I have no intention of playing it (and the OP did not specifically ask for that), I want to look at the code and critique that.

I read that as "try out my game" as in play it. But critiquing code is always good too.

I'm also not in the habit of downloading and running random executable from forums anyhow, especially this one. It only takes one such instance for us to have a repeat of fongerchat.
[/quote]
Well ok. This is true. But I don't hold that blemish against GD.Net. Plus, that's what VMs are for :)

Beginner in Game Development?  Read here. And read here.

 

You have one of the more unusual indentation styles I've ever seen (or was that the forum's useless "helpful" reformatting?). In any case, I will look over this when I get a chance and give you some specifics, but from a quick glance I can suggest two avenues you might want to look at:

  • Consider looking at a system by which you wouldn't need to hard-code collision detection mechanisms between "the ball" and "the wall" -- how could you generalize your collision representation and handling so you could add new things without modifying the ball code?
  • Your sprite manager is rather coupled to your game logic in a few key ways -- for example, "StartGame." How could you factor that dependency out so you can reuse this sprite management code in your next project?
Thanks Josh, you the man. Seriously I appreciate a Engineering Lead taking time out of their day to look am some scrub/noob code.

  • To answer your question about ball/wall collision. I am not really sure how i would do that, but your question has certainly given me something to think about. I don't know if I know a more efficient way to handle that collision.
  • To answer your other question about my Sprite Manager. I suppose I could could have the brick laying in my StartGame() be a method specific to brick rather than it being in the StartGame(). Or maybe i could have my StartGame stuff in the loadcontent

I will really think about how to improve my code. thanks for the head-ups.

This topic is closed to new replies.

Advertisement