原视频: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),
}
}