Unity Tetris Game blocks sometimes not colliding

145 Views Asked by At

I am creating a version of Tetris which uses pentominoes instead of tetrominoes (5 square blocks instead of 4 square blocks). Some of the blocks will sometimes not collide by falling as far as they have space to (gaps between vertically adjacent blocks). Some of the blocks have no problems but some will seemingly randomly leave gaps despite all blocks having the same code attached. Yellow block on the left and light pink block on the left should have fallen further. This can happen with nearly any of the blocks but I do not have an exhaustive list of which ones and when since testing all combinations would take too long.Unity sample space with block names. These are the different blocks with their names. The ones causing the most frequent issues are F left, F right, V, W, Y left and Y right. I have deleted and recreated each block and played around in the prefab assets but the problem still occurs so I think there is a somewhere logic error in my code below:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PentominoCode : MonoBehaviour
{
    private float elapsedTime;
    //This will hold how long since the block last moved down a block
    private float fallSpeed = 0.5f;
    //This is the speed at which the block will fall
    public static int height = 25;
    public static int width = 16;

    private static Transform[,] matrix = new Transform[width, height];
    //This creates a 2D array of the cells taken up by transformed blocks called 'matrix'
    //It has a maxiumum size of height and width as this is the size of the matrix

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow) == true)
        //Checks every frame if the user has pressed the left arrow key
        {
            transform.position += new Vector3(-1, 0, 0);
            //Changes the position of the game object (pentomino block) by the 3D Vector (right -1 (left 1), up 0, forward 0)
            if (InvalidMove() == true)
                //Checks the ValidMove method and if that returns true, the move must be undone
            {
                transform.position -= new Vector3(-1, 0, 0);
                //Undoes the previous move by moving the block in the opposite direction
            }
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow) == true)
        {
            transform.position += new Vector3(1, 0, 0);
            if (InvalidMove() == true)
            {
                transform.position -= new Vector3(1, 0, 0);
            }
        }
        //Same logic as above but for movement right
        else if (Input.GetKeyDown(KeyCode.DownArrow) == true)
        {
            fallSpeed = 0.105f;
            //Sets the falling speed to be 10 times faster
        }
        else if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            transform.eulerAngles += new Vector3(0, 0, -90);
            //Moves the blocks around itself by an angle of -90 degrees anticlockwise (90 deg clockwise)
            if (InvalidMove() == true)
            {
                transform.eulerAngles -= new Vector3(0, 0, -90);
                //Since a rotation may cause one or more block pieces to go beyond the matrix, rotations may have to be undone
            }
        }
        if (Time.time - elapsedTime > fallSpeed)
        //Time.time counts the number of seconds since the game began
        //elapsedTime will be used as a placeholder to hold previous values of Time.time to check time since the blocks last fall.
        {
            transform.position += new Vector3(0, -1, 0);
            elapsedTime = Time.time;
            if (InvalidMove() == true)
            {
                transform.position -= new Vector3(0, -1, 0);
                //This will stop the block falling beyond the matrix
                BlockPlacement();
                //Calls the BlockPlacement method for the current block
                this.enabled = false;
                //Disables the current script so the current block is no longer effected
                FindObjectOfType<SpawnerCode>().SpawnPentomino();
                //Calls the SpawnPentomino method from the game object of the SpawerCode script
            }
            //Sets elapsed time to the last time a block moved down on its own
        }
    }

    void BlockPlacement()
    {
        foreach (Transform children in transform)
        {
            float ValidX = children.transform.position.x;
            float ValidY = children.transform.position.y;

            matrix[(int)ValidX, (int)ValidY] = children;
            //This saves the current coordinates as one of the children of the transform function
        }
    }

    bool InvalidMove()
    //This procedure will check if a move is allowed. A move is allowed if it does not cause a piece to exit the matrix
    {
        foreach (Transform children in transform)
        //This browses all the children of the Transform function

        {
            float ValidX = children.transform.position.x;
            float ValidY = children.transform.position.y;
            //This gets the x and y position of any block that has been transformed in some way

            if (ValidX <= 0 || ValidX >= width || ValidY <= 0)
            //This checks if a piece is outside the matrix
            {
                return true;
                //If a piece is outside the matrix, it is an invalid move
            }
            else if (matrix[(int)ValidX, (int)ValidY] != null)
            //Checks if the current block position is empty
            {
                return true;
                //If the block position is not empty, another block is there so it is an invald move
            }
        }

        return false;
    }

}

Any help as to where my issue may be would be highly appreciated and please feel free to ask any questions.

0

There are 0 best solutions below