Breakout Urban

C#
Unity
⛋ 2D
Uni
06/2018

My first Unity project, made with the help of Trent Williams and Tristan Bondici for a University project. This is a small game made in the space of approximately 6 weeks.

This game uses the core mechanics of Breakout with the added twist that the paddle is now a baseball bat and the ball has the ability to heat up or cool down based on which side of the bat it hits and what bricks it hits. At max-cold or max-heat, the ball will cause either a row or a column of bricks to be destroyed, respectively. The layout of the bricks is entirely randomised with each play-through.

Team:

Liam Dunstan - Designer, Lead Programmer
Trent Williams - Designer, Artist, Programmer
Tristan Bondici - Designer, Sound Designer

1 / 7
2 / 7
3 / 7
4 / 7
5 / 7
6 / 7
7 / 7

Code Snippets

                                void CreateBricks()
{
    // first brick y-pos
    float y = 7.16f;
    // create parent object
    Transform bricks = new GameObject().transform;

    for (int i = 0; i < 6; i++)
    {
        // first brick x-pos
        float x = -4.06f;
        for (int j = 0; j < 6; j++)
        {
            // create brick and add necessary components
            Transform brick = new GameObject().transform;
            brick.parent = bricks;
            brick.position = new Vector3(x, y, 0);
            brick.gameObject.AddComponent<SpriteRenderer>();
            brick.gameObject.AddComponent<BrickScript>();
            brick.gameObject.AddComponent<SpriteShadowScript>();
            brick.gameObject.AddComponent<BoxCollider>();
            brick.name = "brick " + (i + 1) + ", " + (j + 1);

            // set values for components
            brick.gameObject.GetComponent<BoxCollider>().isTrigger = true;
            brick.gameObject.GetComponent<BoxCollider>().size = new Vector3(1.6f, 0.7f, 0.2f);
            brick.gameObject.GetComponent<SpriteShadowScript>().shadCol = new Color(0, 0, 0.05490196f, 0.6862745f);
            SpriteRenderer brSpr = brick.gameObject.GetComponent<SpriteRenderer>();
            BrickScript brScr = brick.gameObject.GetComponent<BrickScript>();

            // random value for brick type
            float rand = Random.Range(0f, 1f);

            // 50% chance of being normal brick
            if (0 <= rand && rand < 0.5f)
            {
                // 6 variants for normal bricks randomly selected per brick
                int rand = Random.Range(1, 7);

                switch (rand)
                {
                    ...
                }

            }
            // 25% chance of being "hot" brick
            else if (0.5 <= rand && rand < 0.75f)
            {
                brSpr.sprite = hotBrick;
                brScr.damageBrickOne = hotBrickDamageOne;
                brScr.damageBrickTwo = hotBrickDamageTwo;
                brick.gameObject.tag = "Hot Brick";
            }
            // 25% chance of being "cold" brick
            else
            {
                brSpr.sprite = coldBrick;
                brScr.damageBrickOne = coldBrickDamageOne;
                brScr.damageBrickTwo = coldBrickDamageTwo;
                brick.gameObject.tag = "Cold Brick";
            }
            x += 1.63f;
        }
        y -= 0.7f;
    }
    bricks.name = "bricks";
}
                            

Excerpt from GameplayController.cs

This snippet outlines the creation process for the bricks. Note how each brick has its type randomised, creating a dynamic set of bricks. This occurs at the beginning of every play-through.

This is how brick creation was handled in the original prototype.

                                void Update()
{
    // if left arrow is pressed
    if (Input.GetKeyUp(KeyCode.LeftArrow))
    {
        // set initial angle and swingState variable
        transform.eulerAngles = new Vector3(-180, 0, 269);
        swingState = -1;
        batSwingSource.Play();

        // call transition method
        StartCoroutine(RotateMe(Vector3.back * 178, 0.2f));
    }
    // if right arrow is pressed
    if (Input.GetKeyUp(KeyCode.RightArrow))
    {
        // set initial angle and swingState variable
        transform.eulerAngles = new Vector3(-180, 0, 91);
        swingState = 1;
        batSwingSource.Play();

        // call transition method
        StartCoroutine(RotateMe(Vector3.forward * 178, 0.2f));
    }
}

/// <summary>
/// method for transitioning the angle of the bat
/// </summary>
/// <param name="byAngles"> Rotation direction and distance </param>
/// <param name="inTime"> Time to complete rotation </param>
/// <returns></returns>
IEnumerator RotateMe(Vector3 byAngles, float inTime)
{
    var fromAngle = transform.rotation;
    var toAngle = Quaternion.Euler(transform.eulerAngles + byAngles);

    for (var t = 0f; t < 1; t += Time.deltaTime / inTime)
    {
        transform.rotation = Quaternion.Slerp(fromAngle, toAngle, t);
        yield return null;
    }
    swingState = 0;
}
                            

Excerpt from BatScript.cs

The code for making the bat swing from one side to the other requires setting an initial angle, either pointing to the left of the screen or the right.

The swingState variable is a public property used by the ball's script for rebound velocity purposes.

The RotateMe method runs as a coroutine and takes parameters of byAngles - how far to rotate and in which direction - and inTime - the time it should take to complete the rotation. Once the rotation is complete the bat's swingState is reset.