Block Breaker
Updated on June 26th, 2021 at 1:08 am
What is it?
This was a project that I made as a final project for a Udemy Course that I took for fun. The goal of the project was to make an Arkanoid-like block-breaking game using my own sprites, my own scripts, and my own physics. The course taught 2D game development with Unity and Block Breaker was one of the chapters in the course. Though this game is not completed, a small demonstration of the game can be played with the link above.
The game was once at a more completed state, but through time, files were lost and now all that remains is a small portion of the game. I am currently working on rebuilding the missing parts so that the game will once again be back to its former glory.
What does it do?
The goal of Block Breaker is to use the paddle at the bottom of the screen to bounce the ball between the paddle and the bricks at the top of the screen. You can move the paddle by dragging the mouse across the screen. If the ball bounces off of a brick, the brick loses a hit point and once the brick is out of hit points, it disappears. The color of the brick determines how many hit points it has. When all of the bricks are removed, the game progresses to the next level.

How does it work?
Block Breaker is powered by the Unity game engine. The project consists of a background sprite, a sprite sheet made of 39 sprites, one font, one material, 3 scenes plus a scene for every level, 6 scripts, and an audio file that loops through the gameplay. I also created 13 prefabs for the paddle, the ball, the background, the level manager, the playspace, and each of the 7 types of bricks.
Sprites
The sprites are from a sprite sheet that I drew with Illustrator. Using Unity, I divided the sprite sheet into fixed-sized blocks that became sprites. Once a sprite was added to a scene, I then made it a prefab of it that could easily be duplicated across the different scenes.

The sprite sheet for the bricks, ball, and paddle support the various cracked versions of bricks for every color (even though they may never appear in the game). This was so that I had the ability to easily change the hit points for each color in the game. At the moment, red bricks only have a single hit point, so you will never see a cracked version in the game, but I can easily change that color to green without having to draw a new sprite sheet. The gray brick does not have cracked variations because it will always be indestructible. I figure it is probably the same material as the paddle.
Scripts
There are six scripts that make up the game. They are written in C#. The ball, paddle, and brick all have their own scripts to dictate how they function in the game. The level manager-script determines which scene to load and when to switch it to the next. The lose-collider script determines how the “Lose Scene” is activated and the music player script is responsible for playing the background music.
Ball.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Ball : MonoBehaviour { private Paddle paddle; private bool hasStarted = false; private Vector3 paddleToBallVector; private Rigidbody2D ball; // Use this for initialization void Start() { paddle = GameObject.FindObjectOfType<Paddle>(); // Place the ball right above the paddle paddleToBallVector = this.transform.position - paddle.transform.position; // Instantiate the ball object as the current classes Rigidbody2d ball = this.GetComponent<Rigidbody2D>(); } // Update is called once per frame void Update() { if (!hasStarted) { // Keep the position of the ball equal to the postion of the paddle this.transform.position = paddle.transform.position + paddleToBallVector; // Launch the ball when mouse is clicked if (Input.GetMouseButtonDown(0)) { Debug.Log("mouse clicked"); ball.velocity = new Vector2(0f, 400f); hasStarted = true; } } } }
Paddle.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Paddle : MonoBehaviour { // Update is called once per frame void Update () { // Get the mouse position on the screen float mousePos = Input.mousePosition.x; // Get the paddle position using the Vector3 structure Vector3 paddlePos = new Vector3(0.0f, this.transform.position.y, 0.0f); // Change the paddle position according to mouse movement paddlePos.x = mousePos; paddlePos.x = Mathf.Clamp(mousePos, 50, 750); this.transform.position = paddlePos; } }
Brick.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Brick : MonoBehaviour { public Sprite[] cracks; public static int breakableCount = 0; private int maxHits; private int timesHit; private bool isBreakable; private Vector3 crackVector; private LevelManager levelManager; // Use this for initialization void Start () { isBreakable = (this.tag == "Breakable"); // Keep track of breakable bricks if (isBreakable) { breakableCount++; } levelManager = GameObject.FindObjectOfType<LevelManager>(); timesHit = 0; } // When the ball hits a brick private void OnCollisionEnter2D(Collision2D collision) { if (isBreakable) { HandleHits(); } } // What happens when a ball hits a brick private void HandleHits() { timesHit++; maxHits = cracks.Length + 1; if (timesHit >= maxHits) { breakableCount--; levelManager.BrickDestroyed(); Destroy(gameObject); } else { LoadSprites(); } } // Handles changing of sprites when a brick is hit private void LoadSprites() { int spriteIndex = timesHit - 1; if (cracks[spriteIndex]) { this.GetComponent<SpriteRenderer>().sprite = cracks[spriteIndex]; } } }
LevelManager.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement; public class LevelManager : MonoBehaviour { // Function to goto a scene public void LoadLevel(string name) { Debug.Log("Level load requested for: " + name); SceneManager.LoadScene(name); } // Function to quit the game public void QuitRequest() { Debug.Log("Game quit"); Application.Quit(); } public void LoadNextLevel() { SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex + 1); } public void BrickDestroyed() { if (Brick.breakableCount <= 0) { LoadNextLevel(); } } }
LoseCollider.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class LoseCollider : MonoBehaviour { private LevelManager levelManager; private void OnTriggerEnter2D(Collider2D trigger) { print("Trigger"); levelManager.LoadLevel("Lose"); } private void Start() { levelManager = GameObject.FindObjectOfType<LevelManager>(); } }
MusicPlayer.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class MusicPlayer : MonoBehaviour { static MusicPlayer instance = null; // Awake called before Start private void Awake() { // Destroy any new instances of MusicPlayer if (instance != null) { Destroy(gameObject); Debug.Log("Duplicate music player self-destructing"); } else { instance = this; GameObject.DontDestroyOnLoad(gameObject); } }