Arkandroid: Let’s make a Breakout Game with Unity3D! – Part 3
Oh don’t be so dramatic, it hasn’t been that long!
Alright! Welcome back to Part 3 of this series on how to make an Arkanoid game! Here’s where we left it last time:
Today it’s time to add a few blocks to break!
In order to do that right, we are finally going to use the Prefabs folder. The reason we haven’t used it yet is that there is no reason to dynamically create new instances of those objects. But blocks are a different story! I don’t really plan to place them on the scene one by one and we could also do some other interesting stuff if the block creation is dynamic, like multiple levels from configuration files etc.
So let’s create our first block prefab. From the Sprites folder, drag and drop one of the colored blocks into the scene. Now let’s put some logic into it!
First off, we want it to collide with the ball. So we’ll have to add a Box Collider 2D component on the Inspector window.
As expected, the ball collides with the block and turns back. But we also want to be able to remove it when we hit it too many times. While we could just add some code and remove it from the scene once it is hit by the ball, on the original Arkanoid game there are blocks that have to be hit multiple times before they are destroyed. And to do that, we will need to introduce a Life variable for the block. So let’s create a new Script called BlockController. Open it and let’s write some code:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class BlockController : MonoBehaviour { public int lives = 2; // Use this for initialization void Start () { } // Update is called once per frame void Update () { } void OnTriggerExit2D(Collider2D col) { lives--; if (live < 1) { Destroy(this.gameObject); } }
If we just do this, nothing will happen. We first have to add it to the block in the Inspector. Then we will have to go back to the ball object and on the Box Collider 2D, check the Is Trigger property so it can trigger the OnTriggerExit event. But even that’s not enough because once we check the option, the collider will, well, stop acting as a collider. So we have to add one more, this time without the Is Trigger property. Now we can run the game and…
The block will get destroyed once its lives run out. Here it had two lives so it took two hit for it to get destroyed. If we wanted a different amount, we can easily change that from the inspector since the lives
property is public.
If we run the game again, the block goes away on the first hit! Perfect!
We need moar blocks!
Okay, let’s be real for a moment, just one block isn’t going to do any good to our game. And that’s why we are now going to add even more!
But first, we’d need a way to add as many blocks as we want to the scene and be able to change their sprites and the number of lives they have. In order to do that, we edit the BlockController as follows:
using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class BlockController : MonoBehaviour { public Sprite[] sprites; public Dictionary<string, Sprite> spritesDictionary = new Dictionary<string, Sprite>(); public int lives = 1; void Start() { UpdateSpritesDictionary(); } void OnTriggerExit2D(Collider2D col) { lives--; if (lives < 1) { Destroy(this.gameObject); } } public void Initialize(string color, int lives) { UpdateSpritesDictionary(); SetColor(color); this.lives = lives; } void SetColor(string color) { this.gameObject.GetComponent<SpriteRenderer>().sprite = spritesDictionary[color]; } void UpdateSpritesDictionary() { foreach (Sprite sprite in sprites) { if (!spritesDictionary.ContainsKey(sprite.name)) { spritesDictionary.Add(sprite.name, sprite); } } } }
Okay, now I really have to explain what is going on here!
sprites
is just a Sprite array for configuring the block sprites on the Inspector so we can then dynamically select a sprite based on its name. Then we convert the array into a Dictionary with a key-value pair the name of the sprite and the sprite itself in order to make it easier to get a specific sprite out of the collection.
On Start()
we call UpdateSpritesDictionary()
. All that it does is insert any sprites from the array into the dictionary.
OnTriggerExit2D()
gets fired every time a collision happens. More specifically as the object that hit the block moves away from it.
We are going to use Initialize()
to set the color and the color (sprite) and the number of lives the block will have when we start instantiating new blocks dynamically.
Remember the sprites
array? Let’s fill it up!
Back on the Unity Editor, click on the block, then on the inspector find the BlockController component. Under the Sprites section, change the size to 7. Click on the small circle on the right of each new element and pick the sprites one by one.
Here’s what it should look like:
Now we have to turn the red block into a Prefab so we can spawn it later on. To do that, let’s rename it to Block and then drag-n-drop it to the Prefabs folder. Then delete it from the scene.
Leave a Reply