【Unity】简易俄罗斯方块(Tetris)制作

原视频:https://www.youtube.com/watch?v=T5P8ohdxDjo

b站转载:【UNITY】13分钟制作出俄罗斯方块!(附下载)_哔哩哔哩_bilibili

一、背景及方块制作关键点

1、要将背景的左下角移到坐标(0,0)点

2、方块的旋转点设置

3、方块坐标需要在整数值

二、脚本

1、TetrisBlock

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class TetrisBlock : MonoBehaviour
{
    public Vector3 rotationPoint;//方块旋转的坐标点
    private float previousTime;
    public float fallTime = 0.8f;//下落时间
    public static int height = 20;//界面高度
    public static int width = 10;//界面宽度
    private static Text points;//分数(消除行数)
    private static int lines = 0;

    public static Transform[,] grid = new Transform[width, height];//界面网格
    // Start is called before the first frame update
    void Start()
    {
        points = GameObject.Find("Points").GetComponent<Text>();
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))//键盘左键
        {
            transform.position += new Vector3(-1, 0, 0);//向左移动一格
            if (!validMove())//判断是否超出界面,超出就反向移动一下抵消
                transform.position -= new Vector3(-1, 0, 0);
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            transform.position += new Vector3(1, 0, 0);
            if (!validMove())
                transform.position -= new Vector3(1, 0, 0);
        }
        else if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            transform.RotateAround(transform.TransformPoint(rotationPoint), new Vector3(0, 0, 1), 90);//旋转点、旋转轴、旋转度数
            if (!validMove())
                transform.RotateAround(transform.TransformPoint(rotationPoint), new Vector3(0, 0, 1), -90);
        }

        if (Time.time - previousTime > (Input.GetKey(KeyCode.DownArrow) ? fallTime/10 : fallTime))//如果按下向下,下落时间改为0.08
        {
            transform.position += new Vector3(0, -1, 0);
            if (!validMove())
            {
                transform.position -= new Vector3(0, -1, 0);
                addToGrid();//不再下落后将对应数据存入网格中
                checkLines();//检查是否有连成一行
                this.enabled = false;
                FindObjectOfType<SpawnTetromino>().newTetromino();//生成下一个方块
            }
            previousTime = Time.time;
        }

        if (Input.GetKey(KeyCode.Escape))
        {
            Application.Quit();
        }

        if (Input.GetKey(KeyCode.Space))
        {
            if (Time.timeScale != 0)
                Time.timeScale = 0;
            else if (Time.timeScale == 0)
                Time.timeScale = 1;
        }
    }

    void checkLines()
    {
        for(int i = height - 1; i >= 0; i--)//对每一行进行扫描
        {
            if (hasLine(i))
            {
                deleteLine(i);
                rowDown(i);//将该行上方的所有方块向下移动一格
                lines++;
                points.text = "Points:" + lines;
            }
        }
    }

    bool hasLine(int i)
    {
        for (int j = 0; j < width; j++)//对每一行中的每一个格子进行扫描
        {
            if (grid[j,i] == null)//只要有一个格子为空就返回false
            {
                return false;
            }
        }
        return true;
    }

    void deleteLine(int i)
    {
        for (int j = 0; j < width; j++)
        {
            Destroy(grid[j, i].gameObject);
            grid[j, i] = null;
        }

    }

    void rowDown(int i)
    {
        for (int y = i; y < height; y++)//选择从第i行往上的所有行
        {
            for (int j = 0; j < width; j++)
            {
                if (grid[j, y] != null)//只要方格不为空
                {
                    grid[j, y - 1] = grid[j, y];//就将方块复制到下一行
                    grid[j, y] = null;//同时清除原本方格中的方块
                    grid[j, y - 1].transform.position -= new Vector3(0, 1, 0);
                }
            }
        }
    }

    void addToGrid()
    {
        foreach (Transform children in transform)
        {
            int roundedX = Mathf.RoundToInt(children.transform.position.x);
            int roundedY = Mathf.RoundToInt(children.transform.position.y);
            grid[roundedX, roundedY] = children;
        }
    }

    bool validMove()
    {
        foreach(Transform children in transform)
        {
            int roundedX = Mathf.RoundToInt(children.transform.position.x);
            int roundedY = Mathf.RoundToInt(children.transform.position.y);
            if(roundedX < 0 || roundedX >= width || roundedY < 0 || roundedY >= height)
            {
                return false;
            }
            if (grid[roundedX, roundedY] != null)
                return false;
        }
        return true;
    }
}

(1)Rotate和RotateAround(围绕旋转):目标点、旋转轴、角度

RotateAround(Vector3 point, Vector3 axis, float angle);

(2) TransformPoint:将相对 “当前游戏对象” 的坐标转化为基于世界坐标系的坐标 

(3)RoundToInt:四舍五入最接近的整数

2、SpawnTetromino

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

public class SpawnTetromino : MonoBehaviour
{
    public GameObject[] Tetrominoes;
    // Start is called before the first frame update
    void Start()
    {
        newTetromino();
    }

    public void newTetromino()
    {
        Instantiate(Tetrominoes[Random.Range(0, Tetrominoes.Length)], transform.position, Quaternion.identity);//Quaternion.identity就是指Quaternion(0,0,0,0),
    }
}

猜你喜欢

转载自blog.csdn.net/simplenthpower/article/details/129469862