Prime Blocks - A Tetris Clone Game For Android/iOS Tutorial

Operating System
In this tutorial I will show how to make an amazing game "Prime Blocks" using a Unity Game Engine and a C# script. Unity is an all purpose game engine that supports 2D and 3D graphics, drag and drop functionality and scripting through C#. UnityScript is a proprietary scripting language which is syntactically similar to JavaScript. Unity is notable for its ability to target games for multiple platforms. So let's get started and see for ourselves.

Getting Started

First you will need to download & install Unit Game Engine, here's the link for the https://store.unity.com/?_ga=2.171981603.1032904231.1505288244-474976023.1495297794 After the Unity Game Engine is Installed , open the unity game engine then we will get started. Here is the interface of the unity game engine when open. tut1 Then Click "NEW", then enter the project name "Prime Blocks ". After entering the name click the 2D button because the game will be make is in 2D environment, and after that place it into your desiganated directory. tut2 This is how the Unity Game Engine Environment look like. tut3 Now we are now ready to create our awesome game.

Game Resolution

First thing to do is to set up our Game resolution, to do that click the game tab then go to "Free Aspect" it is just below of Game tab. Then click the add button (the one that looks like +) and enter the value of each properties. For Width just make it "1080" so that we can have a great resolution for our game, then for Height leave it just "1920". tut4

Categorize Our Assets

We will now then categorze our needed assets, so that we can avoid misplaces and hard to locate our files. Animation - This is where we put all our animator controller and animations Fonts - This where all our fonts is located Resources - This where we put all our prepab object that we will need to make a duplicating objects. Scenes - This is the we put all our scence objects. Scripts - This is where we put all our scripts. Sounds - The directory for our audio files. Sprites - All our images, and sprites can be located here. Note: All our needed assets is already include in the download file. To get the assets just click below the download button.

Creating Main Menu

Creating Scenes

In the Unity environment you will notice an "Untitled" object in the Hierarchy area. That is the name of the scenes by default, to change it just simply press ctrl + s and save it as "Main Menu" tut5

Creating Game Controller

Now that we have the main menu scene we will now create the Game Controller. The Game Controller handles all the save data of our game. To do that just click "GameObject" tab, then a drop down will show up. Then in the sub menu click "Create Empty", a GameObject will appear in the Hierarchy. tut6 Before working on the GameObject make sure to reset its transform to avoid conflict in the future. tut7 After that rename your GameObject as "Game Controller" , then go to the Scripts directory and right click the mouse button, and select create then choose C# script. tut8 Save it as "GameController". Note: To avoid script error make sure the name of your script has no space, because C# is case sensitive to white space. Next open your newly created Script, you notice that there is already a block code in the script. By default the unity engine already created that part to make the developer at ease.
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class GameController : MonoBehaviour {
  6.  
  7.         // Use this for initialization
  8.         void Start () {
  9.                
  10.         }
  11.        
  12.         // Update is called once per frame
  13.         void Update () {
  14.                
  15.         }
  16. }
Now that everything is ready, we will now do our coding thing. First import this important modules.
  1. using System;
  2. using System.IO;
  3. using System.Runtime.Serialization.Formatters.Binary;
Then kindly copy this blocks of code and paste it inside GameController class.
  1. public static GameController instance;
  2.  
  3. public bool isMusicOn;
  4. public bool isGameStartedFirstTime;
  5.  
  6. public int highScore;
  7. public int currentScore;
  8. public int currentLevel;
  9.  
  10. private GameData data;
  11.  
  12. void Awake(){
  13.         CreateInstance ();
  14.         InitializeGameVariables ();
  15. }
  16.  
  17. // Use this for initialization
  18. void Start () {
  19.  
  20. }
  21.  
  22. void CreateInstance(){
  23.         if (instance != null) {
  24.                         Destroy (gameObject);
  25.         }  else {
  26.                 instance = this;
  27.                 DontDestroyOnLoad (gameObject);
  28.         }
  29. }
  30.  
  31. void InitializeGameVariables(){
  32.         Load ();
  33.  
  34.         if (data != null) {
  35.                 isGameStartedFirstTime = data.GetIsGameStartedFirstTime ();
  36.         }  else {
  37.                 isGameStartedFirstTime = true;
  38.         }
  39.  
  40.         if (isGameStartedFirstTime) {
  41.                 isMusicOn = true;
  42.                 isGameStartedFirstTime = false;
  43.                 highScore = 0;
  44.  
  45.                 data = new GameData ();
  46.                 data.SetIsMusicOn (isMusicOn);
  47.                 data.SetIsGameStartedFirstTime (isGameStartedFirstTime);
  48.                 data.SetHighScore (highScore);
  49.  
  50.                 Save ();
  51.  
  52.                 Load ();
  53.         }  else {
  54.                 highScore = data.GetHighScore ();
  55.                 isGameStartedFirstTime = data.GetIsGameStartedFirstTime ();
  56.                 isMusicOn = data.GetIsMusicOn ();
  57.         }
  58.  
  59. }
  60.  
  61.  
  62. public void Save(){
  63.         FileStream file = null;
  64.  
  65.         try{
  66.                 BinaryFormatter bf = new BinaryFormatter();
  67.                 file = File.Create(Application.persistentDataPath + "/save.dat");
  68.  
  69.                 if(data != null){
  70.                         data.SetHighScore(highScore);
  71.                         data.SetIsGameStartedFirstTime(isGameStartedFirstTime);
  72.                         data.SetIsMusicOn(isMusicOn);
  73.                         bf.Serialize(file, data);
  74.                 }
  75.  
  76.         }catch(Exception e){
  77.                 Debug.LogException (e, this);
  78.  
  79.         }finally{
  80.                 if(file != null){
  81.                         file.Close ();
  82.                 }
  83.         }
  84. }
  85.  
  86. public void Load(){
  87.         FileStream file = null;
  88.  
  89.         try{
  90.                 BinaryFormatter bf = new BinaryFormatter();
  91.                 file = File.Open(Application.persistentDataPath + "/save.dat", FileMode.Open);
  92.                 data = bf.Deserialize(file) as GameData;
  93.         }catch(Exception e){
  94.                         Debug.LogException (e, this);
  95.         }finally{
  96.                 if(file != null){
  97.                                 file.Close ();
  98.                 }
  99.         }
  100. }
  101.  
  102.  
  103. [Serializable]
  104. class GameData{
  105.         private bool isGameStartedFirstTime;
  106.         private bool isMusicOn;
  107.  
  108.         private int highScore;
  109.  
  110.         public void SetIsGameStartedFirstTime(bool isGameStartedFirstTime){
  111.                 this.isGameStartedFirstTime = isGameStartedFirstTime;
  112.         }
  113.  
  114.         public bool GetIsGameStartedFirstTime(){
  115.                 return this.isGameStartedFirstTime;
  116.         }
  117.  
  118.         public void SetIsMusicOn(bool isMusicOn){
  119.                 this.isMusicOn = isMusicOn;
  120.         }
  121.  
  122.         public bool GetIsMusicOn(){
  123.                 return this.isMusicOn;
  124.         }
  125.  
  126.         public void SetHighScore(int highScore){
  127.                 this.highScore = highScore;
  128.         }
  129.  
  130.         public int GetHighScore(){
  131.                 return this.highScore;
  132.         }
  133. }
To make this work attach the script to the Game Controller object as a component, by dragging this to the Game Controller Inspector or by clicking add component then go to script and locate the GameController script.

Creating Music Controller

The Music Controller handles all the sounds of the game, this is where you put your game sound clip as an array. Just like what you did on the Game Controller, create a new GameObject then name it as "Music Controller". Then create a new C# script name it as "MusicController". tut9 Inside the Music Controller script, create a certain variable that we will use for our sounds. Write this code inside the Music Controller class.
  1. public static MusicController instance;
  2.  
  3. public AudioClip[] audioClips;
  4.  
  5. [HideInInspector]
  6. public AudioSource audioSource;
Then add this several methods to your script.
  1. void Awake(){
  2.         CreateInstance ();
  3.         audioSource = GetComponent<AudioSource> ();
  4. }
  5.                
  6. void CreateInstance(){
  7.         if (instance != null) {
  8.                 Destroy (gameObject);
  9.         }  else {
  10.                 instance = this;
  11.                 DontDestroyOnLoad (gameObject);
  12.         }
  13. }
  14.  
  15. public void PlayBgMusic(){
  16.         if(!audioSource.isPlaying){
  17.                 AudioClip bgMusic = audioClips [0];
  18.                 if(bgMusic){
  19.                         audioSource.clip = bgMusic;
  20.                         audioSource.loop = true;
  21.                         audioSource.volume = 0.6f;
  22.                         audioSource.Play ();
  23.                 }
  24.         }
  25. }
  26.  
  27. public void GameplaySound(){
  28.         if(!audioSource.isPlaying){
  29.                 AudioClip gameplaySound = audioClips [1];
  30.                 if(gameplaySound){
  31.                         audioSource.clip = gameplaySound;
  32.                         audioSource.loop = true;
  33.                         audioSource.volume = 0.6f;
  34.                         audioSource.Play ();
  35.                 }
  36.         }
  37. }
  38.  
  39. public void StopAllSound(){
  40.         if(audioSource.isPlaying){
  41.                 audioSource.Stop ();   
  42.         }
  43. }
Next you need to attach the script to the Music Controller as a component, it is just the same like you did on Game Controller. tut10 After that add a new component called AudioSource. AudioSource manage the sounds of the game. And uncheck the Play On Wake because it will be done automatically with the script. tut11 Then from the sounds directory drag all the sound into the AudioClips array. tut12

Main Menu UI

The Main Menu UI is a GameObject that hold a several Children component. To Create a UI click the GameObject menu then choose UI then Image. You notice that it automatically create a UI Canvas then your image as a child of it, and also a new object called EvenSytem. EventSystem handle all the trigger event such as when click the buttons, or toggles etc. tut13 Then rename Canvas as "Main Menu UI", and also Image as "Background". In the Main Menu UI set the values same as the image shown below. tut14 To make the Background Image locate your sprite from the Game UI directory then add it to the Background GameObject as a component. tut15 Now that we have the image we will now add two button, just like what you did on the image go to Main Menu UI right click on it select UI then choose Button. Duplicate the button then name them as "Start Button" and "Option Button". See Image Below tut16 Note: When slicing the sprite sheet into a several images you need to select first your image, then in Sprite Mode choose Multiple after that click Sprite Editor. A new Pop up window will appear from here click the Slice on the menu bar, then Slice. It will automatically slice the sheet of a sprite. tut17 tut18 Now that your sprites are ready remove the child text of button, then add a sprite to their components. Then set the values of each GameObject base on the image below.
Start Button
tut19
Option Button
tut20

Main Menu UI - Option Panel, Exit Panel

We will now add two panels in the game, to do that just simple go to the GameObject again then choose panel this time.

Option Panel

In the panel Inspector click color then change its color to #00000, this will act as a background for the panel. Then change its name as Option Panel Background after that add now add a new panel by just right clicking the gameobject then set its name as "Option Panel" and set the components as shown in the inspector below.
Option Panel Background
tut21
Option Panel
tut22 Then add a several children (Text, Button, Toggle) for the Option Panel. After that set the component values as show in the image below.
Text
tut23
Button
tut24
Toggle
tut25 Note: Delete the label text from the children of Toggle, because we will not be needed that for now. The font of the component is already included in the assets folder of the sourcecode file, just simply locate its directory to be able to use.

Exit Panel

Now that we're done with with the other panel. Next we will now create the Exit Panel, exit panel take care of the prompt that closes the app. Just like what you did on the other panel, create new panel then name it as "Exit Panel Background". And create another panel by just right clicking the gameobject then set its name as "Exit Panel" and set the components as shown in the inspector below.
Exit Panel Background
tut26
Exit Panel
tut27 Then add a several children (Text, Buttons) for the Exit Panel. After that set the component values as show in the image below.
Text
tut28
Yes Button
tut29 tut29a
No Button
tut30 tut30a

Creating Main Menu Controller

Now that we have the main menu ui ready we will now create the Main Menu Controller. The Main Menu Controller is the one that handles the option settings and where you start the game, and also trigger some events that necessary needed in the game. To this just simply create a new GameObject name it as Main Menu Controller. Create a script and name MainMenuController. Inside the Main Menu Controller script, create a certain variable that we will use. Write this code inside the Main Menu Controller class.
  1. public GameObject optionPanel, exitPanel, howToPlayPanel;
  2.  
  3. public Toggle musicToggle;
Then add this several methods to your script.
  1. // Use this for initialization
  2. void Start () {
  3.         if (GameController.instance.isMusicOn) {
  4.                 MusicController.instance.PlayBgMusic ();
  5.                 musicToggle.isOn = true;
  6.         }  else {
  7.                 MusicController.instance.StopAllSound ();
  8.                 musicToggle.isOn = false;
  9.         }
  10. }
  11.  
  12. void Update(){
  13.         if(Input.GetKeyDown(KeyCode.Escape)){
  14.                 if (exitPanel.activeInHierarchy) {
  15.                                 exitPanel.SetActive (false);
  16.                 }  else {
  17.                                 exitPanel.SetActive (true);
  18.                 }
  19.  
  20.                 if(optionPanel.activeInHierarchy){
  21.                         optionPanel.SetActive (false);
  22.                 }
  23.  
  24.                 if(howToPlayPanel.activeInHierarchy){
  25.                         howToPlayPanel.SetActive (false);
  26.                 }
  27.         }
  28. }
  29.  
  30. public void StartButton(){
  31.         SceneManager.LoadScene (SceneManager.GetActiveScene ().buildIndex + 1);
  32. }
  33.  
  34. public void OptionButton(){
  35.         optionPanel.SetActive (true);
  36. }
  37.  
  38. public void CloseButton(){
  39.         optionPanel.SetActive (false);
  40. }
  41.  
  42. public void MusicButton(){
  43.         if(musicToggle.isOn){
  44.                 MusicController.instance.PlayBgMusic ();
  45.                 GameController.instance.isMusicOn = true;
  46.                 GameController.instance.Save ();
  47.         }else{
  48.                 MusicController.instance.StopAllSound ();
  49.                 GameController.instance.isMusicOn = false;
  50.                 GameController.instance.Save ();
  51.         }
  52. }
  53.  
  54. public void YesButton(){
  55.         Application.Quit ();
  56. }
  57.  
  58. public void NoButton(){
  59.         exitPanel.SetActive (false);
  60. }
  61.  
  62. public void HowToPlayButton(){
  63.         howToPlayPanel.SetActive (true);
  64. }
  65.  
  66. public void CloseHowToPlay(){
  67.         howToPlayPanel.SetActive (false);
  68. }
Note: When using a UI Components in the script you will just need to import some modules. using UnityEngine.UI; And for loading some scenes you will also need this module using UnityEngine.SceneManagement; Attach the script to the MainMenuController object as a component, as shown in the image. tut31 Note: Make sure you attach the Main Menu Controller to each of the Buttons that you created, this will trigger the methods that we created from the script. tut31a

Creating Level Menu

First create a new scene by pressing ctrl + n then save it in the scene directory as "Level Menu".

Level Menu UI

Next create a image and canvas will be created at the same time. Then rename the canvas as "Level Menu UI" and the image as "Background" Set the component value of the canvas as shown below tut32 Then for the Image tut33

Best Score Text

Now we will add a scoring at the top left of the screen. To do that simply go to the GameObject select UI then choose Text, rename it as "Best" , next add another child text by just right clicking the gameobject text name it as "Highscore Text". Then set the components of each gameobject as shown below.
Best
tut34
Highscore Text
tut35 Then after that add a text name it as "Difficulty Text", then set the values as shown below. tut36 Add a button then set its component as shown below tut37

Level Meter

Next add a UI object that will handle the levels of the game when you start, go to GameObject select UI then choose Slider and also add a new text as an indicator. Rename the slider as "Level Meter" and text as "Level Text". Set the component values as shown below.
Level Text
tut38
Level Meter
tut39

Level Menu Controller

Now that we have the level menu ui, we will now create the Level Menu Controller just like what we did on the main menu. The Level Menu Controller handles the difficulties of the game by increasing or decreasing the Level Meter. To this just simply create a new GameObject name it as "Level Menu Controller". Create then a script and name it "LevelMenuController". Inside the Level Menu Controller script, create a certain variable that we will use. Write this code inside the Main Menu Controller class.
  1. public Slider levelMeter;
  2.  
  3. public Text levelText;
  4. public Text highScore;
  5.  
  6. private int level;
Then add this several methods to your script.
  1. // Use this for initialization
  2. void Start () {
  3.         if(GameController.instance.isMusicOn){
  4.                 MusicController.instance.PlayBgMusic ();
  5.         }else{
  6.                 MusicController.instance.StopAllSound ();      
  7.         }
  8.  
  9.         InitializeLevelController ();
  10. }
  11.  
  12. void Update(){
  13.         if(Input.GetKeyDown(KeyCode.Escape)){
  14.                 SceneManager.LoadScene (SceneManager.GetActiveScene ().buildIndex - 1);
  15.         }
  16.  
  17.         UpdateLevelMenu ();
  18. }
  19.  
  20. void InitializeLevelController(){
  21.         highScore.text = GameController.instance.highScore.ToString ("N0");
  22. }
  23.  
  24. void UpdateLevelMenu(){
  25.         level = (int)levelMeter.value;
  26.         GameController.instance.currentLevel = level;
  27.         levelText.text = level.ToString ();
  28. }
  29.  
  30. public void PlayButton(){
  31.         MusicController.instance.audioSource.Stop ();
  32.         SceneManager.LoadScene (SceneManager.GetActiveScene ().buildIndex + 1);
  33. }
After that attach the script to the Level Menu Controller GameObject, then also attach all the necessary Objects in the script. tut40

Creating The Gameplay

We will now create the gameplay, first thing to do is to create a new scene then save it inside the Scene directory as "Gameplay".

Creating The Blocks

To create the game blocks, we will need to group the blocks as shown in the image below. tut41 The Sprites that we will be needed is in the Sprite directory just locate the sprites and then create a GameObject then place them inside . After that name each of the the game object as Block L, Block O, Block Z, Block S, Block I, Block J, Block T. Note: Before using the blocks make sure you set the Pixels Per Unit to 32 because the game we will make is about 1 pixel per unit block. tut41a

Creating the Block Script

After creating the blocks we will add now the script that will make the block act responsibly in the game. Go to the Script directory then create another directory name it as "Player". In side the new directory create a new script called it "Block". Write this certain variables inside the Block class
  1. public bool canRotate;
  2. public bool minRotate;
  3.  
  4. public AudioClip moveSound;
  5. public AudioClip rotateSound;
  6. public AudioClip landSound;
  7.  
  8. private AudioSource audioSource;
  9.  
  10. private float fallSpeed;
  11. private float fall;
  12. private float verticalMoveSpeed = 0.02f;
  13. private float horizontalMoveSpeed = 0.03f;
  14. private float holdDownDelay = 0.2f;
  15. private float verticalDelay = 0;
  16. private float horizontalDelay = 0;
  17. private float holdDownTimerHorizontal = 0;
  18. private float holdDownTimerVertical = 0;
  19.  
  20. private bool moveHorizontal;
  21. private bool moveVertical;
  22. private bool moved = false;
  23. private bool inPositionBlock;
  24.  
  25. private int touchSensitivityHorizontal = 8;
  26. private int touchSensitivityVertical = 4;
  27.  
  28. private Vector2 prevousUnitPosition = Vector2.zero;
  29. private Vector2 direction = Vector2.zero;
Then add this several methods to your script.
  1. void Awake(){
  2.         tag = "CurrentBlock";
  3.         audioSource = GetComponent<AudioSource> ();
  4.         fallSpeed = GameplayController.instance.fallSpeed;
  5. }
  6.  
  7. // Use this for initialization
  8. void Start () {
  9.  
  10. }
  11.        
  12. // Update is called once per frame
  13. void Update () {
  14.         if (!GameplayController.instance.gameOver && GameplayController.instance.gameInprogress) {
  15.                 if (!inPositionBlock) {
  16.                         PlayerController ();
  17.                         TouchScreen ();
  18.                 }  else {
  19.                         DestroyBlocks ();
  20.                 }
  21.         }
  22.  
  23.  
  24. }
  25.  
  26. void DestroyBlocks(){
  27.         if(transform.childCount <= 0){
  28.                 Destroy (gameObject);
  29.         }
  30. }
  31.  
  32. void TouchScreen(){
  33.         if(Input.touchCount > 0){
  34.                 Touch touch = Input.GetTouch (0);
  35.  
  36.                 if(touch.phase == TouchPhase.Began){
  37.                                 prevousUnitPosition = new Vector2 (touch.position.x, touch.position.y);
  38.                 }else if(touch.phase == TouchPhase.Moved){
  39.                         Vector2 touchDeltaPosition = touch.deltaPosition;
  40.                         direction = touchDeltaPosition.normalized;
  41.  
  42.                 if(Mathf.Abs(touch.position.x - prevousUnitPosition.x) >= touchSensitivityHorizontal && direction.x < 0 && touchDeltaPosition.y > -10 && touchDeltaPosition.y < 10){
  43.                         MoveLeft ();
  44.                         prevousUnitPosition = touch.position;
  45.                         moved = true;
  46.                 }else if(Mathf.Abs(touch.position.x - prevousUnitPosition.x) >= touchSensitivityHorizontal && direction.x > 0 && touch.deltaPosition.y > -10 && touch.deltaPosition.y < 10){
  47.                         MoveRight ();
  48.                         prevousUnitPosition = touch.position;
  49.                         moved = true;
  50.                 }else if(Mathf.Abs(touch.position.y - prevousUnitPosition.y) >= touchSensitivityVertical && direction.y < 0 && touchDeltaPosition.x > -10 && touchDeltaPosition.x < 10){
  51.                         MoveDown ();
  52.                         prevousUnitPosition = touch.position;
  53.                         moved = true;
  54.                 }
  55.  
  56.                 }else if(touch.phase == TouchPhase.Ended){
  57.                         if(!moved && touch.position.x > Screen.width / 4){
  58.                                 Rotate ();
  59.                         }
  60.  
  61.                                 moved = false;
  62.                         }
  63.                 }
  64.  
  65.         if(Time.time - fall >= fallSpeed){
  66.                 MoveDown ();
  67.         }
  68. }
  69.  
  70. void PlayerController(){
  71.         if(Input.GetKeyUp(KeyCode.RightArrow) || Input.GetKeyUp(KeyCode.LeftArrow)){
  72.                 moveHorizontal = false;
  73.                 horizontalDelay = 0;
  74.                 holdDownTimerHorizontal = 0;
  75.         }
  76.  
  77.         if (Input.GetKeyUp (KeyCode.DownArrow)) {
  78.                 moveVertical = false;
  79.                 horizontalDelay = 0;
  80.                 holdDownTimerVertical = 0;
  81.         }
  82.  
  83.         if(Input.GetKey(KeyCode.RightArrow)){
  84.                 MoveRight ();
  85.         }
  86.  
  87.         if(Input.GetKey(KeyCode.LeftArrow)){
  88.                 MoveLeft ();
  89.         }
  90.  
  91.         if(Input.GetKeyDown(KeyCode.UpArrow)){
  92.                 Rotate ();
  93.         }
  94.  
  95.         if(Input.GetKey(KeyCode.DownArrow) || Time.time - fall >= fallSpeed ){
  96.                 MoveDown ();
  97.         }
  98. }
  99.  
  100. private bool CheckCorrectPosition(){
  101.         foreach(Transform block in transform){
  102.                        
  103.                 Vector2 position = GameplayController.instance.Estimate (block.position);
  104.  
  105.                 if(GameplayController.instance.CheckBlockInside(position) == false){
  106.                         return false;  
  107.                 }
  108.  
  109.                 if(GameplayController.instance.GetGridPosition(position) != null && GameplayController.instance.GetGridPosition(position).parent != transform){
  110.                         return false;
  111.                 }
  112.         }
  113.  
  114.         return true;
  115. }
  116.  
  117. void MoveLeft(){
  118.         if (moveHorizontal) {
  119.                 if (holdDownTimerHorizontal < holdDownDelay) {
  120.                         holdDownTimerHorizontal += Time.deltaTime;
  121.                         return;
  122.                 }
  123.  
  124.                 if (horizontalDelay < horizontalMoveSpeed) {
  125.                         horizontalDelay += Time.deltaTime;
  126.                         return;
  127.                 }
  128.  
  129.         }
  130.  
  131.         if(!moveHorizontal){
  132.                 moveHorizontal = true;
  133.         }
  134.  
  135.         horizontalDelay = 0;
  136.  
  137.  
  138.         transform.position += new Vector3 (-1, 0, 0);
  139.  
  140.         if (CheckCorrectPosition ()) {
  141.                 GameplayController.instance.UpdateGrid (this);
  142.                 if(GameController.instance.isMusicOn){
  143.                         audioSource.PlayOneShot (moveSound);
  144.                 }
  145.         }  else {
  146.                 transform.position += new Vector3 (1, 0, 0);
  147.         }
  148.  
  149.  
  150. }
  151.  
  152. void MoveRight(){
  153.         if (moveHorizontal) {
  154.                 if (holdDownTimerHorizontal < holdDownDelay) {
  155.                         holdDownTimerHorizontal += Time.deltaTime;
  156.                         return;
  157.                 }
  158.  
  159.                 if (horizontalDelay < horizontalMoveSpeed) {
  160.                         horizontalDelay += Time.deltaTime;
  161.                         return;
  162.                 }
  163.  
  164.         }
  165.  
  166.         if(!moveHorizontal){
  167.                 moveHorizontal = true;
  168.         }
  169.  
  170.         horizontalDelay = 0;
  171.  
  172.         transform.position += new Vector3 (1, 0, 0);
  173.  
  174.         if (CheckCorrectPosition ()) {
  175.                 GameplayController.instance.UpdateGrid (this);
  176.                 if(GameController.instance.isMusicOn){
  177.                         audioSource.PlayOneShot (moveSound);
  178.                 }
  179.         }  else {
  180.                 transform.position += new Vector3 (-1, 0, 0);
  181.         }
  182.  
  183. }
  184.  
  185. void MoveDown(){
  186.         if (moveVertical) {
  187.  
  188.                 if (holdDownTimerVertical < holdDownDelay) {
  189.                         holdDownTimerVertical += Time.deltaTime;
  190.                         return;
  191.                 }
  192.  
  193.  
  194.                 if (verticalDelay < verticalMoveSpeed) {
  195.                         verticalDelay += Time.deltaTime;
  196.                         return;
  197.                 }
  198.  
  199.         }
  200.  
  201.         if (!moveVertical) {
  202.                 moveVertical = true;
  203.         }
  204.  
  205.         verticalDelay = 0;
  206.  
  207.  
  208.         transform.position += new Vector3 (0, -1, 0);
  209.  
  210.         if (CheckCorrectPosition ()) {
  211.                 GameplayController.instance.UpdateGrid (this);
  212.  
  213.         }  else {
  214.  
  215.                 transform.position += new Vector3 (0, 1, 0);
  216.  
  217.                 GameplayController.instance.DeleteRow ();
  218.  
  219.                 if(GameplayController.instance.CheckOutsideGrid (this)){
  220.                         GameplayController.instance.GameOver ();
  221.                 }
  222.  
  223.                 if(!GameplayController.instance.gameOver){
  224.                         GameController.instance.currentScore += Random.Range (1, 15);
  225.                 }
  226.                 tag = "InPositionBlock";
  227.  
  228.                 inPositionBlock = true;
  229.  
  230.                 if(GameController.instance.isMusicOn){
  231.                         audioSource.PlayOneShot (landSound);
  232.                 }
  233.  
  234.                 GameplayController.instance.SpawnNextBlock ();
  235.  
  236.  
  237.         }
  238.         fall = Time.time;
  239. }
  240.  
  241. void Rotate(){
  242.         if(canRotate){
  243.                 if (minRotate) {
  244.  
  245.                         if (transform.rotation.eulerAngles.z >= 90) {
  246.                                 transform.Rotate (0, 0, -90);
  247.  
  248.                         }  else {
  249.                                 transform.Rotate (0, 0, 90);
  250.                         }
  251.  
  252.                 }  else {
  253.  
  254.                         transform.Rotate (0, 0, 90);
  255.                 }
  256.  
  257.  
  258.                 if (CheckCorrectPosition ()) {
  259.                         GameplayController.instance.UpdateGrid (this);
  260.                         if(GameController.instance.isMusicOn){
  261.                                 audioSource.PlayOneShot (rotateSound);
  262.                         }
  263.                 }else {
  264.  
  265.                         if (minRotate) {
  266.                                 if (transform.rotation.eulerAngles.z >= 90) {
  267.                                         transform.Rotate (0, 0, -90);
  268.  
  269.                                 }  else {
  270.                                                 transform.Rotate (0, 0, 90);
  271.                                         }
  272.                                 }  else {
  273.                                         transform.Rotate (0, 0, -90);
  274.                         }
  275.  
  276.  
  277.                 }
  278.  
  279.  
  280.  
  281.         }
  282. }
After that attached a AudioSource component and attach the script to each of the blocks, then drag all the needed sounds in the script. tut41b After we're done making the blocks, you will need to prefabs each of the gameobject so that we can use it later. In the Resources Directory create a new directory name it as "Prefabs" then inside the Prefbas directory create again a new directory namely "Blocks". After making the directory drag all the GameObject inside the Blocks Directory as show in the image below. tut42 You'll notice that when you drag all the GameObjects in assets the name of the gameobject in the Hierarchy will turn blue, also will a add a new option in the inspector tut43 tut44 First thing to do is to adjust our camera set the value of its components as show below tut45 Note: We configure the Camera because our game itself is a grid base, when we spawn the blocks we just need to locate the absolute value of the x and y coordinate to place the block in exact position. The Game UI take care the visual of the game, To do that go to GameObject then select the Image. Rename The canvas as "Game UI" and the image as "Background UI".
Game UI
tut46
Background UI
tut47

Right Panel

Now we will create the right panel, this will display the status of the game. Like displaying the score, the preview of block etc. To do that create another Image from Game UI then name it as "Right Panel". Set its component values as shown below. tut48 Now we will add some Images to make the game stunning. Add at least 5 Images, then name as: *Score Background *Score Text Background *Level Background *Lines Background *Preview Background After that set all the component values as shown in the image.
Score Background
tut49 Then add a text GameObject the set its components same as the image below tut50
Score Text Background
tut51 Then add a text GameObject the set its components same as the image below tut52
Level Background
tut53 Then add a two text GameObject then set the components same as the image below
Level
tut54
Level Text
tut55
Lines Background
tut56 Then add a two text GameObject then set the components same as the image below
Lines
tut57
Lines Text
tut58
Preview Background
tut59 Then after that add a several images, this will display the blocks that will be drop later. Set its component values in the inspector same as the image shown below.
Image I
tut60
Image J
tut61
Image L
tut62
Image T
tut63
Image Z
tut64
Image S
tut65
Image O
tut66

Pause Button

Now that we're done with the right panel we will then add a button in the Game UI that handles the stopping of the game. Then set it component values as shown below tut67 This will be the output of the Game UI that we created. tut68

Creating The Grid And Background Gameplay

We will now create the the grid and the background of the gameplay. The Tetris scene will be 10 blocks wide and 22 high. The coordinate is between (0, 0) and (9, 21). Create a GameObject then name it as "Grid", and we will divide the grid children as follow: Top, Bottom, Left, Right;
Bottom
In the bottom drag 12 blocks inside the GameObject and arrange it from 0 x axis to 11 x axis accordingly tut69
Left
In the left drag 22 blocks inside the GameObject and arrange it from (0x, 0y) to (0x, 22y) ordinates It will be look like this tut70
Right
To make this simple just duplicate the left GameObject and rename it as "Right", then set its children x axis to 11. tut71
Top
To make this simple again just duplicate the bottom GameObject and rename it as "Top", then set its children y axis to 23. tut72 This will be the grid look like after you've done

Background Gameplay

We will create the background gameplay, this will act as UI for the blocks background. To that create a GameObject then name it as "Background Gameplay", and drag black block inside of the GameObject then set it position (0x, 0y). Then duplicate each blocks, and place it 1 block away from each other as shown in the image below. tut73

Creating Gameplay UI

This will handle the prompt for the GameOver and Pause. To do that create another Canvas, then name it as "Gameplay UI" and set it component as shown below tut74 After that add a two panels inside the new canvas and name it as "Pause Panel Background" and "GameOver Panel Background". Then set it component as shown below
Pause Panel Background
tut75 Then add another panel called it "Pause Panel" and set its component as shown below tut76 Inside the Pause Panel add Text, and two Buttons, then set their components as shown in the image
Pause Text
tut77
Resume Button
tut78
Quit Button
tut79

GameOver Panel Background

tut80 Then add another panel inside of it namely "GameOver Panel", then set its component as shown below tut81 Then add several components inside the new panel (2 Buttons, 2 Text), then set their components as shown below
GameOver Text
tut82
Score Text
tut83 Then add additional text inside the score text name it as "Highscore Text", this will display when the player achieved a highscore.
Highscore Text
tut84
Restart Button
tut85
Quit Button
tut86 Note: Don't forget to attach the Gameplay Controller in the buttons, and also attach all the needed components in the Gameplay Controller Script as shown below. tut87

Building The Game

To build the game go to the file menu, then choose Build Setting. After that drag all the scenes in the empty box and set the platform to android as shown below. tut88 After you're done select the Player Setting, then fill up the required information in order to build the application. tut89 Once you're done try to start the game by the clicking the play button tut90 Congratulations you successfully created the Tetris Clone Game. I hope that this simple tutorial help you develop your skills in building games. For more updates and tutorials just kindly visit this site. Enjoy Coding!!!

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. After downloading it, you will need a program like Winzip to decompress it.

Virus note: All files are scanned once-a-day by SourceCodester.com for viruses, but new viruses come out every day, so no prevention program can catch 100% of them.

FOR YOUR OWN SAFETY, PLEASE:

1. Re-scan downloaded files using your personal virus checker before using it.
2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.

Add new comment