Exemple #1
0
    /// <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);
    }
Exemple #2
0
    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;
    }
Exemple #3
0
    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;
        }
    }
Exemple #6
0
 //- 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);
 }
Exemple #7
0
    // 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();
            }
        };
    }
Exemple #8
0
 //- 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;
 }
Exemple #10
0
    /// <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();
                }
            }
        }
    }