/// <summary> /// Clear all blocks from a specified line. /// </summary> /// <param name="lineToClear">Index of the line to be cleared.</param> void ClearLine(int lineToClear) { if (lineToClear < 0 || lineToClear > gridHeight) { return; } for (int x = 0; x < gridWidth; x++) { TetrominoController curTetroContrl = _grid[x, lineToClear].blockOnGrid.GetComponent <TetrominoBlockController>().tetroController; curTetroContrl.blocks[_grid[x, lineToClear].blockOnGrid.GetComponent <TetrominoBlockController>().blockIdx] = null; Destroy(_grid[x, lineToClear].blockOnGrid); if (!curTetroContrl.AnyBlocksLeft()) { Destroy(curTetroContrl.gameObject); } _grid[x, lineToClear].blockOnGrid = null; _grid[x, lineToClear].isOccupied = false; } // Play Clear line sound GameSystem.gsInstance.soundContrl.audioSource.PlayOneShot(GameSystem.gsInstance.soundContrl.clearLineSound); }
void OnEnable() { // Drop time reduces when the game level goes up dropTime = 1 - GameSystem.gsInstance.gameLevel * 0.1f; // Assign TetrominoSystem Component tetroSystem = GameObject.FindObjectOfType <TetrominoSystem>(); // Assign attached blocks to blocks list blocks = new TetrominoBlockController[4]; for (int i = 0; i < blocks.Length; i++) { TetrominoBlockController newBlock = transform.GetChild(0).GetChild(i).GetComponent <TetrominoBlockController>(); blocks[i] = newBlock; } // Assign TetrominoController to current tetromino variable curTetroController = gameObject.GetComponent <TetrominoController>(); curBlocks = gameObject; // Assign touch controller event TouchController.swipeEvent += SwipeHandler; TouchController.swipeEndEvent += SwipeEndHandler; TouchController.tapEvent += TapHandler; }
private void CreateNewPiece() { game.NewPiece(); Destroy(currentPiece); currentPiece = gameObject.AddComponent <TetrominoController>(); Texture texture = PieceTextures[game.CurrentPiece.type]; currentPiece.SetPiece(game.CurrentPiece, texture, CubeParent); allCubes.AddRange(currentPiece.blocks); }
private void SettingCurrentTetromino() { currentTetromino = tetrominoQueue.dequeue(); currentTetromino.transform.SetParent(this.transform); currentTetromino.transform.position = spawnPoint; tetrominoController = currentTetromino.GetComponent <TetrominoController>(); if (!tetrominoController) { tetrominoController = currentTetromino.AddComponent <TetrominoController>(); } }
private void SettingGhostTetromino() { ghostTetromino = Instantiate(currentTetromino, this.transform); ghostController = ghostTetromino.GetComponent <TetrominoController>(); var renderers = ghostTetromino.GetComponentsInChildren <Renderer>(); foreach (var renderer in renderers) { Color color = renderer.material.color; color.a = 0.5f; renderer.material.color = color; } }
//- call to chick Game Over - player losser public bool checkIsAboveGrid(TetrominoController obj) { for (int x = 0; x < gridWiedth; x++) { foreach (Transform mino in obj.transform) { Vector2 pos = Round(mino.position); if (pos.y > gridHieght - 1) { return(true); } } } return(false); }
// Use this for initialization void Awake() { blocks = new int [20, 10]; tetromino = tetrominoObj.GetComponent <TetrominoController> (); queue = queueObj.GetComponent <NextTetrominos> (); hold = holdObj.GetComponent <HoldTetromino> (); networkBlocks = ""; justSpanwed = true; gameRunning = false; dropDelay = 1f; dropDelayCounter = dropDelay; ResetCurrentPos(); x = new int[4]; y = new int[4]; startX = -1.88f; startY = 4.005f; InitializeBlocksObj(); UpdateBlocksState(); randomedTetrominos = new int[4]; RandomTetrominos(); holdUsed = false; pushUsed = false; time = 120f; score = 0; FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("https://tetris-a8118.firebaseio.com/"); // Get the root reference location of the database. reference = FirebaseDatabase.DefaultInstance.RootReference; reference.ValueChanged += (object sender, ValueChangedEventArgs args) => { if (args.DatabaseError != null) { Debug.LogError(args.DatabaseError.Message); return; } if (args.Snapshot.Child(myEnemy).HasChild("score")) { escore = args.Snapshot.Child(myEnemy).Child("score").Value.ToString(); } }; }
//- update the grid state as tetriminos moveed , deleted and spwaned public void updateGrid(TetrominoController tetromino) { for (int i = 0; i < gridWiedth; i++) { for (int j = 0; j < gridHieght; j++) { if (grid[i, j] != null) { if (grid[i, j].parent == tetromino.transform) { grid[i, j] = null; } } } } foreach (Transform mino in tetromino.transform) { Vector2 pos = Round(mino.position); if (pos.y < gridHieght) { grid[(int)pos.x, (int)pos.y] = mino; } } }
/// <summary> /// Initialize current tetromino blocks variables. /// </summary> /// <param name="tetroContrl">Reference to the TetrominoController that the blocks are associated with.</param> /// <param name="idx">Index of the blocks that attched to the current tetromino.</param> public void InitializeBlocks(TetrominoController tetroContrl, int idx) { tetroController = tetroContrl; blockIdx = idx; }
/// <summary> /// Check if the last movement is rotation. /// Then, if any of the three points of the adjacent 3x3 T shape is occupied /// </summary> public bool IsValidTSpinPoint(TetrominoController curTetroContrl) { // How T-Spin is determined? // Todo: // 1. Check if the current type is T shape and last movement is rotation // 2. If Three of the 4 squares diagonally adjacent to the T's center are occupied, return true as a valid TSpin; // In Tetris DS, the walls and floor surrounding the playfield are considered "occupied", // 3. For each point, use IsInBound and IsOuccupied (IsInBound() == false || IsPositionEmpty() == false) to mark the point as valid point. // 4. Otherwise, return false; // More info: // https://tetris.fandom.com/wiki/T-Spin // Create vectors for diagonal check // There are two cases we need to consider. // Case 1: The flat side of the T surface facing left or right. // Case 2: The flat side of the T surface facing up or down. // Case 1 Example: (X is the point that needs to be checked.) // X || X X || X // ||==== ====|| // X || X X || X // Case 2 Example: // X || X X X // ======== ======== // X X X || X // For Case 1: Vector2Int[] pointVecHorizontal = new Vector2Int[] { new Vector2Int(1, 0), new Vector2Int(-1, 0) }; // For Case 2: Vector2Int[] pointVecVertical = new Vector2Int[] { new Vector2Int(0, 1), new Vector2Int(0, -1) }; // Points count - If valid points are greater or equal to three, then the T-Spin is valid. int pointsCount = 0; // Case 1: Loop through blocks and check both side of the block 2 and block 4 points. // Case 2: Loop through blocks and check the points above block 2 and block 4, then check the points below block 2 and block 4 for (int i = 1; i < 4; i += 2) { // Inside block 2 and block 4 // Check points next for (int j = 0; j < 2; j++) { // If block2.coordinates.x equals to block4.coordinates.x, then it's case 1 if (curTetroContrl.blocks[1].coordinates.x == curTetroContrl.blocks[3].coordinates.x) { Debug.Log("Inside T-Spin case 1 condition!!!"); Vector2Int pointToCheck = curTetroContrl.blocks[i].coordinates + pointVecHorizontal[j]; // If IsInBounds is false, the diagonal points are kicking the wall. if (IsInBounds(pointToCheck) == false) { pointsCount++; } else { // If IsPositionEmpty is false, the diagonal points are occupied by other tetrominoes. if (IsPositionEmpty(pointToCheck) == false) { pointsCount++; } } } // If block2.coordinates.x not equals to block4.coordinates.x, then it's case 2 else { Debug.Log("Inside T-Spin case 2 condition!!!"); Vector2Int pointToCheck = curTetroContrl.blocks[i].coordinates + pointVecVertical[j]; // If IsInBounds is false, the diagonal points are kicking the wall. if (IsInBounds(pointToCheck) == false) { pointsCount++; } else { // If IsPositionEmpty is false, the diagonal points are occupied by other tetrominoes. if (IsPositionEmpty(pointToCheck) == false) { pointsCount++; } } } } } Debug.Log("The T-Spin points count is " + pointsCount); // If three diagonal points are valid and any of the line is cleared by the T tetromino, then T-Spin is valid // The line cleared check is in TetrominoController.cs at line 350 if (pointsCount >= 3) { // Set line cleared false for next round isLineCleared = false; return(true); } else { // Set line cleared false for next round isLineCleared = false; return(false); } }
/// <summary> /// Hold the current tetromino in the game scene for later use. /// </summary> public void HoldCurrentTetromino() { // Hold is only possible when the tetromino location is above the middle line of the play field if (tetroController.isHoldable == true && tetroController.blocks[0].coordinates.y >= 11) { // Initial hold if (holdTetromino == null) { tetroController.isHoldable = false; // Stop the current tetromino coroutine tetroController.StopTetrominoDrop(); // Assign current tetromino holdTetromino = currentTetromino; // Turn off the tetromino controller that on hold holdTetromino.GetComponent <TetrominoController>().enabled = false; // Move the hold tetromino out of the grid holdTetromino.transform.position = new Vector3(10, 25, 0); // Add tetromino sprite to hold box AddHoldTetrominoSprite(holdTetromino.GetComponent <TetrominoController>().curType); // Spawn the next tetromino SpawnController.instance.SpawnTetromino(); } // Subsequent hold - Swtich the current tetromino and hold tetromino else { tetroController.isHoldable = false; // Assign temporaly game object before switch GameObject tmpTetromino = currentTetromino; Vector2Int[] blocksCoordinates = tmpTetromino.GetComponent <TetrominoController>().GetBlocksCoordinates(); // Swap is possible if the surrounding grid of the current block is empty bool isGridEmpty = false; Vector2Int[] surroundVec = new Vector2Int[] { new Vector2Int(0, -1), new Vector2Int(0, 1), new Vector2Int(-1, 0), new Vector2Int(1, 0) }; // If the blocks in bound and for (int i = 0; i < blocksCoordinates.Length; i++) { foreach (var item in surroundVec) { // Check if the current block surrounding grid are empty int newX = blocksCoordinates[i].x + item.x; int newY = blocksCoordinates[i].y + item.y; if (GridSystem.gridInstance.IsInBounds(new Vector2Int(newX, newY))) { isGridEmpty = GridSystem.gridInstance.IsPositionEmpty(new Vector2Int(newX, newY)); } if (!isGridEmpty) { break; } } } // If surrounding are empty. Perform the swap operation if (isGridEmpty) { // Turn off the current tetromino coroutine tetroController.StopTetrominoDrop(); // Assign current tetromino the hold with tmp tetromino holdTetromino.SetActive(true); currentTetromino = holdTetromino; currentTetromino.GetComponent <TetrominoController>().enabled = true; tetroController = currentTetromino.GetComponent <TetrominoController>(); currentTetromino.transform.position = tmpTetromino.transform.position; // Update the current blocks position after swap Vector2Int newPos = new Vector2Int((int)blocksCoordinates[1].x, (int)blocksCoordinates[1].y); // Check if updating the current blocks position after swap would out of the grid boundary. int leftBound = Mathf.Abs(newPos.x - 0); int rightBound = Mathf.Abs(newPos.x - 10); bool isLeftBound = leftBound < 2 ? true : false; bool isRightBound = rightBound <= 2 ? true : false; // If none of the blocks is out of the boundary, update the tetromino at the new position. if (isLeftBound == false && isRightBound == false) { tetroController.blocks[0].UpdatePosition(newPos); tetroController.UpdateBlocksPosition(newPos); } // If any of the blocks position is outside of the right boundary, move the new position X coordinate left 1 unit else if (isLeftBound == false && isRightBound == true) { newPos.x -= 1; // Edge case: if the current tetromino type is I type // Then move the new position X coordinate 1 unit further if (tetroController.curType == TetrominoType.I) { newPos.x -= 1; } tetroController.blocks[0].UpdatePosition(newPos); tetroController.UpdateBlocksPosition(newPos); } // If any of the blocks position is outside of the left boundary, move the new position X coordinate right 1 unit else if (isLeftBound == true && isRightBound == false) { newPos.x += 1; tetroController.blocks[0].UpdatePosition(newPos); tetroController.UpdateBlocksPosition(newPos); } // Switch the current tetromino and on hold tetromino holdTetromino = tmpTetromino; // Update hold tetromino position holdTetromino.GetComponent <TetrominoController>().enabled = false; AddHoldTetrominoSprite(holdTetromino.GetComponent <TetrominoController>().curType); holdTetromino.transform.position = new Vector3(10, 25, 0); // Temporarily turn off the hold object holdTetromino.SetActive(false); // Start current tetromino drop after switch tetroController.StartTetrominoDrop(); } } } }