Atari Breakout Game Development in C# with Windows Forms GUI
VerifiedAdded on 2023/06/13
|27
|3183
|447
Project
AI Summary
This C# project details the design and development of the Atari 2600 classic "Breakout" game. The application initializes the graphical user interface (GUI) components, lays out layers of bricks, and waits for player input. Listeners monitor the ball's position and brick collisions, removing bricks upon impact and updating the player's score on the GUI. The ball's trajectory is managed by functions that handle collisions with the paddle and play area walls. Developed in C# with a user interface defined in XML, the game utilizes classes for Ball, Paddle, and Brick objects, all within the PongBrickGame namespace. The main form, drawn at runtime, employs graphics drawing functionalities to render the playfield, bricks, paddle, and ball, facilitating easier control and object interaction.

Introduction
This project entails the design and development of a version of the Atari2600 classic “breakout” game.
This is a simple classic arcade game, developed in 1976 by a company called Atari Inc; inspired by a
1972 Atari arcade Pong game that had been developed by Steve Jobs and Steve Wozniak1. The game
contains layers of bricks, which are broken by a bouncing ball. The ball is reflected to the bricks by a
moveable paddle platform at the bottom; which is moved by a player horizontally to bounce the ball
upwards.
Design of the Game
Figure 1.0 Game control flow chart diagram
The game follows a simple design where when the application is started; it first initializes the
Graphical user interface components, then lays out layers of bricks, before waiting for a player to
start playing the game. When the game is started, various listeners keep check of the ball’s
position and the bricks. When a brick is hit by the ball, the brick is removed from the view, and
the ball reflected back. A function handles the change of direction of the ball. This function also
handles the ball when it hits the paddle platform as well as when it hits the walls of the play area.
Brick removal calls the method to increment the player’s score, which is automatically updated
on the GUI.
The application was developed in C#, to ensure that the application User interface is as robust
and lightweight as possible; the user interface was defined in xml and called in C#.
1. Thomasson, Michael. "Atari VCS 2600." Encyclopedia of Video Games: MZ 2 (2012): 52.
This project entails the design and development of a version of the Atari2600 classic “breakout” game.
This is a simple classic arcade game, developed in 1976 by a company called Atari Inc; inspired by a
1972 Atari arcade Pong game that had been developed by Steve Jobs and Steve Wozniak1. The game
contains layers of bricks, which are broken by a bouncing ball. The ball is reflected to the bricks by a
moveable paddle platform at the bottom; which is moved by a player horizontally to bounce the ball
upwards.
Design of the Game
Figure 1.0 Game control flow chart diagram
The game follows a simple design where when the application is started; it first initializes the
Graphical user interface components, then lays out layers of bricks, before waiting for a player to
start playing the game. When the game is started, various listeners keep check of the ball’s
position and the bricks. When a brick is hit by the ball, the brick is removed from the view, and
the ball reflected back. A function handles the change of direction of the ball. This function also
handles the ball when it hits the paddle platform as well as when it hits the walls of the play area.
Brick removal calls the method to increment the player’s score, which is automatically updated
on the GUI.
The application was developed in C#, to ensure that the application User interface is as robust
and lightweight as possible; the user interface was defined in xml and called in C#.
1. Thomasson, Michael. "Atari VCS 2600." Encyclopedia of Video Games: MZ 2 (2012): 52.
Paraphrase This Document
Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser

To make it easy to control the game’s logic, a number of classes were developed, each
representing a single object; such as Ball, Paddle and Brick. Each of these objects interacts with
one another to and are the foundation of the game.
The programs main functions and algorithms are contained in the PongBrickGame namespace.
The main form that makes the GUI is empty and is drawn at runtime.
Figure 1.0 Main Form of the application,
We use the graphics drawing functionalities to draw the playfield, the bricks, paddle and the ball
at runtime. Since each object is modeled in a class of its own, it’s an easier approach.
representing a single object; such as Ball, Paddle and Brick. Each of these objects interacts with
one another to and are the foundation of the game.
The programs main functions and algorithms are contained in the PongBrickGame namespace.
The main form that makes the GUI is empty and is drawn at runtime.
Figure 1.0 Main Form of the application,
We use the graphics drawing functionalities to draw the playfield, the bricks, paddle and the ball
at runtime. Since each object is modeled in a class of its own, it’s an easier approach.

Figure 2: Game GUI when the Game is started
Figure 3.0 GUI when the game is being played
Figure 3.0 GUI when the game is being played
⊘ This is a preview!⊘
Do you want full access?
Subscribe today to unlock all pages.

Trusted by 1+ million students worldwide

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace PongBrickGame
{
/// <summary>
/// This class simply paints the
/// FORM to create the Games's
/// graphical user interface
/// </summary>
public class Game
{
protected Image image = null;
public Point startPosition = new Point(50, 50);
protected Rectangle playFieldBounds = new Rectangle(0,0, 10, 10);
protected Rectangle moveableBounds = new Rectangle();
public Game(string fileName)
{
image = Image.FromFile(fileName);
playFieldBounds.Width = image.Width;
playFieldBounds.Height = image.Height;
}
public int Width
{
get
{
return playFieldBounds.Width;
}
}
public int Height
{
get
{
return playFieldBounds.Height;
}
}
public virtual int GetWidth()
{
return playFieldBounds.Width;
}
public Image GetImage()
{
return image;
}
public virtual Rectangle GetBounds()
{
return moveableBounds;
}
public void UpdateBounds()
using System.Drawing;
using System.Drawing.Drawing2D;
namespace PongBrickGame
{
/// <summary>
/// This class simply paints the
/// FORM to create the Games's
/// graphical user interface
/// </summary>
public class Game
{
protected Image image = null;
public Point startPosition = new Point(50, 50);
protected Rectangle playFieldBounds = new Rectangle(0,0, 10, 10);
protected Rectangle moveableBounds = new Rectangle();
public Game(string fileName)
{
image = Image.FromFile(fileName);
playFieldBounds.Width = image.Width;
playFieldBounds.Height = image.Height;
}
public int Width
{
get
{
return playFieldBounds.Width;
}
}
public int Height
{
get
{
return playFieldBounds.Height;
}
}
public virtual int GetWidth()
{
return playFieldBounds.Width;
}
public Image GetImage()
{
return image;
}
public virtual Rectangle GetBounds()
{
return moveableBounds;
}
public void UpdateBounds()
Paraphrase This Document
Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser

{
moveableBounds = playFieldBounds;
moveableBounds.Offset(startPosition);
}
public virtual void Draw(Graphics g)
{
UpdateBounds();
g.DrawImage(image, moveableBounds, 0, 0, playFieldBounds.Width,
playFieldBounds.Height, GraphicsUnit.Pixel);
}
}
}
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
namespace PongBrickGame
{
/// <summary>
/// The main Class of this application.
moveableBounds = playFieldBounds;
moveableBounds.Offset(startPosition);
}
public virtual void Draw(Graphics g)
{
UpdateBounds();
g.DrawImage(image, moveableBounds, 0, 0, playFieldBounds.Width,
playFieldBounds.Height, GraphicsUnit.Pixel);
}
}
}
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
using System.Threading;
namespace PongBrickGame
{
/// <summary>
/// The main Class of this application.

/// It forms the whole game
/// </summary>
public class BrickBreaker : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private const int noOfBricksRows = 8;
private const int noOfTiles = 3;
private int totalBrickOnTheForm = 0;
private int noOfBalls = 0;
private Ball ball = new Ball();
private Paddle playerPaddle = new Paddle();
private System.Windows.Forms.Timer timer1;
private RowOfBricks[] rows = new RowOfBricks[noOfBricksRows];
private Score playerScore = null;
private Thread gameThread = null;
[DllImport("winmm.dll")]
public static extern long PlaySound(String lpszName, long hModule, long dwFlags);
/// <summary>
/// The main constructor of the application
/// calls the InitializeComponents() function
/// which greates the GUI
/// </summary>
public BrickBreaker()
{
InitializeComponent();
/// </summary>
public class BrickBreaker : System.Windows.Forms.Form
{
private System.ComponentModel.IContainer components;
private const int noOfBricksRows = 8;
private const int noOfTiles = 3;
private int totalBrickOnTheForm = 0;
private int noOfBalls = 0;
private Ball ball = new Ball();
private Paddle playerPaddle = new Paddle();
private System.Windows.Forms.Timer timer1;
private RowOfBricks[] rows = new RowOfBricks[noOfBricksRows];
private Score playerScore = null;
private Thread gameThread = null;
[DllImport("winmm.dll")]
public static extern long PlaySound(String lpszName, long hModule, long dwFlags);
/// <summary>
/// The main constructor of the application
/// calls the InitializeComponents() function
/// which greates the GUI
/// </summary>
public BrickBreaker()
{
InitializeComponent();
⊘ This is a preview!⊘
Do you want full access?
Subscribe today to unlock all pages.

Trusted by 1+ million students worldwide

for (int i = 0; i < noOfBricksRows; i++)
{
rows[i] = new RowOfBricks(i);
}
playerPaddle.startPosition.X = 5;
playerPaddle.startPosition.Y = this.ClientRectangle.Bottom - playerPaddle.Height;
ball.startPosition.Y = this.ClientRectangle.Bottom - 200;
this.SetBounds(this.Left, this.Top, rows[0].GetBounds().Width, this.Height);
playerScore = new Score(ClientRectangle.Right - 50, ClientRectangle.Bottom - 180);
//THIS SPECIFIES RE-PAINT INTERVALS
//THE HIGHER THE REPAINT-INTERVAL THE SLOWER THE GAME
timer1.Interval = 100;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
{
rows[i] = new RowOfBricks(i);
}
playerPaddle.startPosition.X = 5;
playerPaddle.startPosition.Y = this.ClientRectangle.Bottom - playerPaddle.Height;
ball.startPosition.Y = this.ClientRectangle.Bottom - 200;
this.SetBounds(this.Left, this.Top, rows[0].GetBounds().Width, this.Height);
playerScore = new Score(ClientRectangle.Right - 50, ClientRectangle.Bottom - 180);
//THIS SPECIFIES RE-PAINT INTERVALS
//THE HIGHER THE REPAINT-INTERVAL THE SLOWER THE GAME
timer1.Interval = 100;
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
Paraphrase This Document
Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser

base.Dispose( disposing );
}
private string m_strCurrentSoundFile = "BallOut.wav";
public void PlayASound()
{
if (m_strCurrentSoundFile.Length > 0)
{
PlaySound(Application.StartupPath + "\\" + m_strCurrentSoundFile, 0, 0);
}
m_strCurrentSoundFile = "";
gameThread.Abort();
}
public void PlaySoundInThread(string wavefile)
{
m_strCurrentSoundFile = wavefile;
gameThread = new Thread(new ThreadStart(PlayASound));
gameThread.Start();
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
}
private string m_strCurrentSoundFile = "BallOut.wav";
public void PlayASound()
{
if (m_strCurrentSoundFile.Length > 0)
{
PlaySound(Application.StartupPath + "\\" + m_strCurrentSoundFile, 0, 0);
}
m_strCurrentSoundFile = "";
gameThread.Abort();
}
public void PlaySoundInThread(string wavefile)
{
m_strCurrentSoundFile = wavefile;
gameThread = new Thread(new ThreadStart(PlayASound));
gameThread.Start();
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()

{
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// BrickBreaker
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(552, 389);
this.KeyPreview = true;
this.Name = "Brick Breaker";
this.Text = "Bricks Breaker Game";
this.Load += new System.EventHandler(this.Form1_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.KeyDown += new
System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// The main method calls the constructor of this class
/// to initialize the game
this.components = new System.ComponentModel.Container();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.SuspendLayout();
//
// timer1
//
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
//
// BrickBreaker
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(552, 389);
this.KeyPreview = true;
this.Name = "Brick Breaker";
this.Text = "Bricks Breaker Game";
this.Load += new System.EventHandler(this.Form1_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.Form1_Paint);
this.KeyDown += new
System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// The main method calls the constructor of this class
/// to initialize the game
⊘ This is a preview!⊘
Do you want full access?
Subscribe today to unlock all pages.

Trusted by 1+ million students worldwide

/// </summary>
[STAThread]
static void Main()
{
Application.Run(new BrickBreaker());
}
/// <summary>
/// Paint the GUI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
g.FillRectangle(Brushes.White, 0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height);
playerScore.Draw(g);
playerPaddle.Draw(g);
DrawRows(g);
ball.Draw(g);
}
/// <summary>
/// Create Rows of bricks
/// </summary>
/// <param name="g"></param>
private void DrawRows(Graphics g)
{
for (int i = 0; i < noOfBricksRows; i++)
{
[STAThread]
static void Main()
{
Application.Run(new BrickBreaker());
}
/// <summary>
/// Paint the GUI
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
g.FillRectangle(Brushes.White, 0, 0, this.ClientRectangle.Width,
this.ClientRectangle.Height);
playerScore.Draw(g);
playerPaddle.Draw(g);
DrawRows(g);
ball.Draw(g);
}
/// <summary>
/// Create Rows of bricks
/// </summary>
/// <param name="g"></param>
private void DrawRows(Graphics g)
{
for (int i = 0; i < noOfBricksRows; i++)
{
Paraphrase This Document
Need a fresh take? Get an instant paraphrase of this document with our AI Paraphraser

rows[i].Draw(g);
}
}
/// <summary>
/// Detects Collition btw the ball and the walls
///
/// </summary>
private void detectCollition()
{
//if if hits the left wall, change direction
if (ball.startPosition.X < 0)
{
ball.Xmove *= -1;
ball.startPosition.X += ball.Xmove;
PlaySoundInThread("WallHit.wav");
}
//Hits the top of the playfield
if (ball.startPosition.Y < 0)
{
ball.Ymove *= -1;
ball.startPosition.Y += ball.Ymove;
PlaySoundInThread("WallHit.wav");
}
// hit the left side
if (ball.startPosition.X > this.ClientRectangle.Right - ball.Width )
{
}
}
/// <summary>
/// Detects Collition btw the ball and the walls
///
/// </summary>
private void detectCollition()
{
//if if hits the left wall, change direction
if (ball.startPosition.X < 0)
{
ball.Xmove *= -1;
ball.startPosition.X += ball.Xmove;
PlaySoundInThread("WallHit.wav");
}
//Hits the top of the playfield
if (ball.startPosition.Y < 0)
{
ball.Ymove *= -1;
ball.startPosition.Y += ball.Ymove;
PlaySoundInThread("WallHit.wav");
}
// hit the left side
if (ball.startPosition.X > this.ClientRectangle.Right - ball.Width )
{

ball.Xmove *= -1;
ball.startPosition.X += ball.Xmove;
PlaySoundInThread("WallHit.wav");
}
//Ball is out of the playfield bounds
if (ball.startPosition.Y > this.ClientRectangle.Bottom - ball.Ymove)
{
IncrementGameBalls();
Reset();
PlaySoundInThread("BallOut.wav");
}
if (RowsCollide(ball.startPosition))
{
ball.Ymove *= -1;
PlaySoundInThread("BrickHit.wav");
}
int hp = HitsPaddle(ball.startPosition);
if (hp > -1)
{
PlaySoundInThread("PaddleHit.wav");
switch (hp)
{
case 1:
ball.Xmove = -7;
ball.Ymove = -3;
break;
ball.startPosition.X += ball.Xmove;
PlaySoundInThread("WallHit.wav");
}
//Ball is out of the playfield bounds
if (ball.startPosition.Y > this.ClientRectangle.Bottom - ball.Ymove)
{
IncrementGameBalls();
Reset();
PlaySoundInThread("BallOut.wav");
}
if (RowsCollide(ball.startPosition))
{
ball.Ymove *= -1;
PlaySoundInThread("BrickHit.wav");
}
int hp = HitsPaddle(ball.startPosition);
if (hp > -1)
{
PlaySoundInThread("PaddleHit.wav");
switch (hp)
{
case 1:
ball.Xmove = -7;
ball.Ymove = -3;
break;
⊘ This is a preview!⊘
Do you want full access?
Subscribe today to unlock all pages.

Trusted by 1+ million students worldwide
1 out of 27
Your All-in-One AI-Powered Toolkit for Academic Success.
+13062052269
info@desklib.com
Available 24*7 on WhatsApp / Email
Unlock your academic potential
Copyright © 2020–2025 A2Z Services. All Rights Reserved. Developed and managed by ZUCOL.