We continue making a Tetris clone in this video. Our goal this time is to get those Tetris shapes to stack on each other. A lot more goes into that then we may have thought. I’ll be covering Simulating Game boards in Arrays, Printing Arrays, Removing Event Handling from Objects, Instantiating Objects, Debugging, Moving All Shapes in a Scene and a whole lot more.
I continue with my new teaching format in which I make mistakes and then fix them to help you learn. All of the code follows the video below.
If you like videos like this, consider donating $1 on Patreon, or just turn off AdBlock. That helps a lot.
[googleplusone]
Code from The Video
SHAPESPAWNER.CS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShapeSpawner : MonoBehaviour { // Array that holds all the shapes public GameObject[] shapes; public void SpawnShape() { // Generate a random index int shapeIndex = Random.Range(0, 6); // Create the shape at the ShapeSpawners location Instantiate(shapes[shapeIndex], transform.position, Quaternion.identity); } // Use this for initialization void Start () { // Spawn the default first shape SpawnShape(); } // Update is called once per frame void Update () { } } |
GAMEBOARD.CS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class GameBoard : MonoBehaviour { // ---------- NEW STUFF ---------- // Surround all GameObjects with GameObjectGroup // and move it the amount of space to make the // gameboard lie at the 0 0 mark // Stores all the cubes on the gameboard public static Transform[,] gameBoard = new Transform[10, 20]; public static void PrintArray() { string arrayOutput = ""; // Gets size of gameboard array and then subtract // 1 because the array starts with 0 int iMax = gameBoard.GetLength(0) - 1; int jMax = gameBoard.GetLength(1) - 1; // Cycle through the array and print N or X // depending on if you have a null or transform for(int j = jMax; j >= 0; j--) { for (int i = 0; i <= iMax; i++) { if (gameBoard[i, j] == null) { arrayOutput += "N "; } else { arrayOutput += "X "; } } arrayOutput += "\n \n"; } // Get a reference to the Text component // and change its value var myArrayComp = GameObject.Find("MyArray").GetComponent<Text>(); myArrayComp.text = arrayOutput; } } |
SHAPE.CS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Shape : MonoBehaviour { // Define that we want to fall 1 unit per second public float speed = 1.0f; // Tracks the last time the shape moved down float lastMoveDown = 0; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetKeyDown("a")) { // Modify position transform.position += new Vector3(-1, 0, 0); if (!IsInGrid()) { // Switch to previous transform.position += new Vector3(1, 0, 0); } else { // Update the GameBoard array UpdateGameBoard(); } } if (Input.GetKeyDown("d")) { transform.position += new Vector3(1, 0, 0); if (!IsInGrid()) { transform.position += new Vector3(-1, 0, 0); } else { UpdateGameBoard(); } } // Move Shape down when s is pressed, or once every second // First time through Time.time will have a value of 1 and // then 2, etc. // lastMoveDown will increment each time through as well if (Input.GetKeyDown("s") || Time.time - lastMoveDown >= 1) { transform.position += new Vector3(0, -1, 0); if (!IsInGrid()) { transform.position += new Vector3(0, 1, 0); // Disconnect the script actions from the shape enabled = false; // Spawn another shape FindObjectOfType<ShapeSpawner>().SpawnShape(); } else { UpdateGameBoard(); } lastMoveDown = Time.time; } if (Input.GetKeyDown("w")) { transform.Rotate(0, 0, 90); if (!IsInGrid()) { transform.Rotate(0, 0, -90); } else { UpdateGameBoard(); } } if (Input.GetKeyDown("e")) { transform.Rotate(0, 0, -90); if (!IsInGrid()) { transform.Rotate(0, 0, 90); } else { UpdateGameBoard(); } } } public bool IsInGrid() { // Cycle through every block in the shape foreach(Transform childBlock in transform) { // Get location of the block and round to int Vector2 vect = RoundVector(childBlock.position); // Check if the position is within the border if (!IsInBorder(vect)) { return false; } // Check what is located in the GameBoard array // This should be its own method if(GameBoard.gameBoard[(int)vect.x, (int)vect.y] != null && GameBoard.gameBoard[(int)vect.x, (int)vect.y].parent != transform) { return false; } } return true; } // Round the cubes position to an int so it can fit // in the array public Vector2 RoundVector(Vector2 vect) { return new Vector2(Mathf.Round(vect.x), Mathf.Round(vect.y)); } // Check if between the border public static bool IsInBorder(Vector2 pos) { return ((int)pos.x >= 0 && (int)pos.x <= 9 && (int)pos.y >= 0); } // public void UpdateGameBoard() { for(int y = 0; y < 20; ++y) { for(int x = 0; x < 10; ++x) { // If the 1st isn't null that means there // is a cube at that position // Then we check if the shape passed in // is already there if (GameBoard.gameBoard[x, y] != null && GameBoard.gameBoard[x, y].parent == transform) { // If the shape moves down then we want // to remove it from the gameBoard array GameBoard.gameBoard[x, y] = null; } } } // Iterate over all spaces on our gameboard // and add the new cubes for out shape foreach (Transform childBlock in transform) { // Shorten our position object Vector2 vect = RoundVector(childBlock.position); // Put our cube in the gameboard array GameBoard.gameBoard[(int)vect.x, (int)vect.y] = childBlock; Debug.Log("Cube At : " + vect.x + " " + vect.y); } GameBoard.PrintArray(); } } |
Leave a Reply