传统俄罗斯方块
Posted 无畏先锋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传统俄罗斯方块相关的知识,希望对你有一定的参考价值。
using UnityEngine;
using System.Collections;
public class MetrixTools {
//全局静态方法,随机获取(返回)一种形状
public static int[,] GetRandomMetrix() {
int id = Random.Range(0, 7);
switch (id)
{
case 0:
return new int[,] {
{1, 1},
{1, 1}
};
case 1:
return new int[,] {
{0, 0, 0 },
{0, 1, 0 },
{1, 1, 1 }
};
case 2:
return new int[,] {
{0, 0, 0 },
{0, 1, 1 },
{1, 1, 0 }
};
case 3:
return new int[,] {
{0, 0, 0 },
{1, 1, 0 },
{0, 1, 1 }
};
case 4:
return new int[,] {
{0, 0, 0 },
{1, 0, 0 },
{1, 1, 1 }
};
case 5:
return new int[,] {
{0, 0, 0 },
{0, 0, 1 },
{1, 1, 1 }
};
case 6:
return new int[,] {
{0, 0, 0, 0 },
{1, 1, 1, 1 },
{0, 0, 0, 0 },
{0, 0, 0, 0 }
};
default:
return null;
}
}
//全局静态方法,第一个循环实现矩阵转置,第二个循环实现左右对调
public static void RotateMetrix(int[,] metrix) {
for (int i = 0; i < metrix.GetLength(0); i++)
{
for (int j = 0; j < i; j++)
{
int temp = metrix[i, j];
metrix[i, j] = metrix[j, i];
metrix[j, i] = temp;
}
}
//左上角为00点,上下为i 左右为j
for (int i = 0; i < metrix.GetLength(0); i++)
{
for (int left = 0, right = metrix.GetLength(1) - 1; left < right; left++, right--)
{
int temp = metrix[i, left];
metrix[i, left] = metrix[i, right];
metrix[i, right] = temp;
}
}
}
}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class GridMetrix{
public int i, j;
public int[,] metrixData;//矩阵数据
//随机生成数组,得到一个形状
public GridMetrix(){
metrixData = MetrixTools.GetRandomMetrix ();
}
public void MoveDown(){
i++;
}
public void MoveLeft(){
j--;
}
public void MoveRight(){
j++;
}
//旋转矩阵
public void Rotate()
{
MetrixTools.RotateMetrix (metrixData);
}
}
public class Map : MonoBehaviour {
public const int MaxRow = 18;//地图列长
public const int MaxCol = 12;//地图宽
private int[,] mapData;
private GameObject[,] gridArr;
private GridMetrix curMetrix;
// Use this for initialization
void Start () {
//初始化地图
//每秒刷新地图
Init();
InvokeRepeating ("ChangeMap", 0f, 0.5f);//每0.5s调用一次ChangeMap函数
}
//将生成的所有地图格子放入数组gridArr中
void Init()
{
mapData = new int[MaxRow, MaxCol];
gridArr = new GameObject[MaxRow, MaxCol];
GameObject gridPrefab = Resources.Load<GameObject> ("grid");
for (int i = 0; i < MaxRow; i++) {
for (int j = 0; j < MaxCol; j++) {
GameObject grid = Instantiate (gridPrefab);
grid.name = j.ToString () + " " + i.ToString ();
grid.transform.SetParent (transform);
grid.transform.localScale = Vector3.one;
grid.GetComponent<Image>().enabled = false;
gridArr [i, j] = grid;
}
}
}
void ChangeMap(){
//如果没有cube,创建一个
//如果检测能下落
//cube下落,刷新地图
//否则
//检测是否失败
//把cube加入地图
//消除cube,刷新地图
if (curMetrix == null) {
curMetrix = CreateGridMetrix ();
}
if (CanMoveDown ()) {
curMetrix.MoveDown ();
}else
{
if (curMetrix.i <= 0)
{
Debug.Log ("少侠,请再次来过");
Time.timeScale = 0;
}
AddMetrixToMap ();
ClearGridInLine ();
}
RefreshMap ();
}
//记录矩阵在地图中的位置,并且刷新地图数组相关位置的信息
void AddMetrixToMap(){
int[,] data = curMetrix.metrixData;
for (int i = 0; i < data.GetLength(0); i++) {
for (int j = 0; j < data.GetLength(1); j++) {
if (data [i, j] == 1)
{
int mapI = curMetrix.i + i;
int mapJ = curMetrix.j + j;
if (mapI >= 0)
{
mapData [mapI, mapJ] = 1;
}
}
}
}
curMetrix = null;
}
//根据地图数组的信息,显示对应位置cube
void RefreshMap(){
for (int i = 0; i < MaxRow; i++) {
for (int j = 0; j < MaxCol; j++) {
gridArr [i, j].GetComponent<Image>().enabled = (mapData [i, j] == 1);
}
}
if (curMetrix == null) {
return;
}
//记录当前方块在地图中的信息并且显示相应的地图方块
int[,] data = curMetrix.metrixData;
for (int i = 0; i < data.GetLength(0); i++) {
for (int j = 0; j < data.GetLength(1); j++) {
if (data [i, j] == 1) {
int mapI = curMetrix.i + i;
int mapJ = curMetrix.j + j;
if (mapI >= 0) {
gridArr [mapI, mapJ].GetComponent<Image>().enabled = true;
}
}
}
}
}
//创建一个方块并且初始化它的位置
GridMetrix CreateGridMetrix()
{
GridMetrix metrix = new GridMetrix ();
metrix.i = - metrix.metrixData.GetLength(0);
metrix.j = Random.Range(0, MaxCol - metrix.metrixData.GetLength(1));
return metrix;
}
//如果地图上当前格子的下面没有cube 就可以下落 返回true
bool CanMoveDown()
{
int tempI = curMetrix.i + 1;
int tempJ = curMetrix.j;
return IsOK (tempI, tempJ, curMetrix.metrixData);
}
bool CanMoveLeft(){
int tempI = curMetrix.i;
int tempJ = curMetrix.j - 1;
return IsOK (tempI, tempJ, curMetrix.metrixData);
}
bool CanMoveRight()
{
int tempI = curMetrix.i;
int tempJ = curMetrix.j + 1;
return IsOK (tempI, tempJ, curMetrix.metrixData);
}
bool IsOK(int tempI, int tempJ, int[,] metrix){
for (int i = 0; i < metrix.GetLength(0); i++) {
for (int j = 0; j < metrix.GetLength(1); j++) {
if (metrix [i, j] == 1) {
int mapI = tempI + i;
int mapJ = tempJ + j;
if(!IsPointOK(mapI, mapJ)){
return false;
}
}
}
}
return true;
}
//地图中的点是否合法
bool IsPointOK(int mapI, int mapJ){
if (mapI > MaxRow - 1 || mapJ < 0 || mapJ > MaxCol - 1) {
return false;
}
if (mapI >= 0 && mapData [mapI, mapJ] == 1) {
return false;
}
return true;
}
// Update is called once per frame
void Update () {
if (curMetrix == null)
return;
if (Input.GetKeyDown (KeyCode.LeftArrow) && CanMoveLeft ()) {
curMetrix.MoveLeft ();
RefreshMap ();
}else if(Input.GetKeyDown(KeyCode.RightArrow) && CanMoveRight()){
curMetrix.MoveRight ();
RefreshMap ();
}else if(Input.GetKeyDown(KeyCode.Space)){
curMetrix.Rotate ();
RefreshMap ();
}
//快速下降
if (Input.GetKey (KeyCode.DownArrow)) {
Time.timeScale = 10f;
} else {
Time.timeScale = 1f;
}
}
//消除算法
void ClearGridInLine(){
int factor = 0;
for (int i = MaxRow -1; i >= 0; i--)
{
int sum = 0;
for (int j = 0; j < MaxCol; j++)
{
mapData [i + factor, j] = mapData [i, j];
if (mapData [i, j] == 1)
{
sum++;
}
}
if (sum >= MaxCol) {
factor++;
}
}
for (int i = 0; i < factor; i++) {
for (int j = 0; j < MaxCol; j++) {
mapData [i, j] = 0;
}
}
}
}
以上是关于传统俄罗斯方块的主要内容,如果未能解决你的问题,请参考以下文章