Making the Blocks and Ball


Goal

The basic block in BICS causes a deduction of 20 from the player scores, flashes red, makes a sound, before it is Destroyed( ).

The ball used in BICS makes sounds upon the start of the level, pauses every-time it spawns for 3 seconds before it starts moving, and makes sounds when it hits anything. It also has only 3 lives (3 chances for respawn before a fail-state).

Code

Blue-block code:

using UnityEngine;
using System.Collections;
public class Block : MonoBehaviour
{
    public AudioSource crashSource;
    public AudioSource punishment;
    private bool crashed; //this bool is used for starting timer for punishment sounds/animations
    public double duration = .3; //timer duration
    public int timeRemaining;
    public bool blockfinishCount; //to detect when the timer finish
    //timer components
    public GameObject penalty;
    //penalty text UI gameObject
    void Start()
    {
        crashSource = GetComponent<audiosource>();
        penalty.GetComponent<spriterenderer>().enabled = false; //text is disabled
        crashed = false; //has not collided with ball
        blockfinishCount = false;
    }
    void OnCollisionEnter2D(Collision2D collisionInfo)
    {
        crashSource.Play();
        punishment.Play();
        Debug.Log("play sound");
        crashed = true; //has collided
        Invoke("Begin", .3f);
        //
        ScoreCounter.scoreValue -= 20;
        TOTALscore.TotalscoreValue -= 20;
        TOTALscore.changeinscore += 20;
        //
        penalty.GetComponent<spriterenderer>().enabled = true; //text appears
        //The block turns red
        GetComponent<spriterenderer>().color = new Color(225f, 0f, 0f, 225f);
        //the ball cannot collide with the block again
        GetComponent<boxcollider2d>().enabled = false;
    }
    public void Begin()
    {
        if (timeRemaining == 0)
        {
            Debug.Log("block timer end");
            blockfinishCount = true;
            GetComponent<spriterenderer>().enabled = false;//the block is not rendered, but script continue
        }
    }
    void Update()
    {
        if (crashed)
        {
            if (!crashSource.isPlaying)//if the sound finished playing after ball has collided
            {
                Debug.Log("finished playing sound!");
                // Destroy the whole Block once the sound has finished
                Destroy(gameObject);
            }
            else
            {
                //animation of the text upwards until block is Destroyed
                penalty.transform.position += transform.up * 1f *
                10 * Time.deltaTime;
            }
        }
    }
}

The Ball script contains a timer for the pause after the spawn and connects to the text displaying the ball's 3 lives:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Ball_28feb : MonoBehaviour
{
    // Movement Speed
    public float speed;
    //Timer components
    public int duration;
    public int timeRemaining;
    public bool isCountingDown;
    public bool finishCount;
    //spawn timer indication in level
    public GameObject SpawnText;
    Text spawn;
    //hitting feedback: this sound plays whoever it collider with anything
    public AudioSource mooSource;
    //display for Life number
    public GameObject LifeText;
    //"LifeCounter" is another script. I am fetching the bool from that script
    public LifeCounter thebool;
    float hitFactor(Vector2 ballPos, Vector2 racketPos,
                float racketWidth)
    {
        // ascii art:
        //
        // 1  -0.5  0  0.5   1  <- x value
        // ===================  <- racket
        //this is from the code in the Arkanoid tutorial
        return (ballPos.x - racketPos.x) / racketWidth;
    }
    // Use this for initialization
    void Start()
    {
        GetComponent<rigidbody2d>().velocity = Vector3.zero; //ball is stationary at start
        mooSource = GetComponent<audiosource>();
        thebool = LifeText.GetComponent<lifecounter>();//access the script called "lifecounter" in the "lifeText" gameObject
        isCountingDown = false;
        finishCount = false;
        spawn = SpawnText.GetComponent<text>();//text that only appears during spawn pause
        Invoke("Begin", 1f);//timer start once level start
    }
    void OnCollisionEnter2D(Collision2D col)
    {
        // Hit the Racket?
        if (col.gameObject.name == "racket")
        {
            // Calculate hit Factor
            float x = hitFactor(transform.position,
                              col.transform.position,
                              col.collider.bounds.size.x);
            // Calculate direction, set length to 1
            Vector2 dir = new Vector2(x, 1).normalized;
            // Set Velocity with dir * speed
            GetComponent<rigidbody2d>().velocity = dir * speed;
            //play sound
            mooSource.Play();
            Debug.Log("play moo");
        }
        //Hit DespawnZone (a 2d collision area)
        if (col.gameObject.name == "DespawnZone")
        {
            Debug.Log("restart ball position");
            transform.position = new Vector3(0, -240, 0);//teleport ball to spawn location
            GetComponent<rigidbody2d>().velocity = Vector3.zero;//ball stop moving
            Invoke("Begin", 1f);//timer start again for the length of spawn pause
            LifeCounter.lifeValue -= 1;
            thebool.haveplayedforthislife = false;//fetch bool to set it in this script
            //the bool controls whether or not sound can play when a life is deducted
            //being put here makes sure that the bool is on false so the sound will play once
        }
    }
    private void Update()
    {
        if (finishCount)//currently timer has finished and isn't counting down
        {
            GetComponent<rigidbody2d>().velocity = Vector2.down * speed;
            Debug.Log("Carry On");
            finishCount = false; //reset the bool
            this.GetComponent<spriterenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);//the ball is no longer semi-transparent
            SpawnText.GetComponent<text>().enabled = false;
        }
        if (isCountingDown)
        {
            GetComponent<rigidbody2d>().velocity = Vector3.zero;//ball still stop moving
            Debug.Log("pause");
        }
        spawn.text = "Spawning in " + timeRemaining;
    }
    public void Begin()//called when timer is supposed to start
    {
        if (!isCountingDown)
        {
            isCountingDown = true;
            this.GetComponent<spriterenderer>().material.color = new Color(1.0f, 1.0f, 1.0f, 0.5f);//ball slightly transparent
            SpawnText.GetComponent<text>().enabled = true;
            timeRemaining = duration;
            Invoke("Cont", 1f);
        }
    }
    private void Cont()
    {
        timeRemaining--;
        if (timeRemaining > 0)
        {
            Invoke("Cont", 1f);
        }
        else
        {
            isCountingDown = false;
            finishCount = true;
        }
    }
}

The ball's life counter is contained in another script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class LifeCounter : MonoBehaviour
{
    public static int lifeValue = 3;
    public float playerscore = 3;
    Text score;
    public GameObject Life1;
    public GameObject Life2;
    public GameObject Life3;
    //these are the sprites that each display a logo for one life
    public AudioSource nopeSource;
    private bool play;//this triggers the sound to play
    public bool haveplayedforthislife;//check if the sound has already been triggered for this particular life deduction
    void Start()
    {
        score = GetComponent<text>();
        play = false;
        haveplayedforthislife = false;
}
    // printed in ui
    void Update()
    {
        score.text = "Life " + lifeValue;
        playerscore = lifeValue;
        //now get it to game over
        if (lifeValue == 0)
        {
            if (!haveplayedforthislife)//not yet play sound
            {
                if (!nopeSource.isPlaying)//if sound is not playing
                {
                    play = true;//sound is allowed to play
                    haveplayedforthislife = true;//bool set to true
                }
                if (nopeSource.isPlaying)//currently playing sound
                {
                    play = false;//sound not allowed to start again
                }
            }
            else
            {
                play = false;//no sound should play
            }
            Destroy(Life3);
            SceneManager.LoadScene("Death");
            Debug.Log("YouDied");
        }
        if (lifeValue == 2)
        {
            if (!haveplayedforthislife)
            {
                if (!nopeSource.isPlaying)
                {
                    play = true;
                    haveplayedforthislife = true;
                }
                if (nopeSource.isPlaying)
                {
                    play = false;
                }
            }
            else
            {
                play = false;
            }
            Destroy(Life1);
        }
        if (lifeValue == 1)
        {
            if (!haveplayedforthislife)
            {
                if (!nopeSource.isPlaying)
                {
                    play = true;
                    haveplayedforthislife = true;
                }
                if (nopeSource.isPlaying)
                {
                    play = false;
                }
            }
            else
            {
                play = false;
            }
            Destroy(Life2);
        }
        if (play)//if sound is supposed to play
        {
            nopeSource.Play();
            Debug.Log("play nope");
            if (nopeSource.isPlaying)
            {
                play = false;//reset bool
            }
            else //finished playing sound
            {
                haveplayedforthislife = true;
                Debug.Log("finish playing");
            }
        }
    }
    private void OnLevelWasLoaded(int level)
    {
        lifeValue = 3;//reset life to 3
    }
}

That's all for this post! In the next and last post about BICS code, I'll share with you how popups work :)

Get Bull in a china shop

Leave a comment

Log in with itch.io to leave a comment.