传统俄罗斯方块

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;
            }
        }
    }
}

 

以上是关于传统俄罗斯方块的主要内容,如果未能解决你的问题,请参考以下文章

C++俄罗斯方块

求用JAVA编写俄罗斯方块游戏的源代码

C# 俄罗斯方块源代码

俄罗斯方块游戏

java如何用图形界面显示二维数组俄罗斯方块

俄罗斯方块进阶--AI俄罗斯方块