首页 > 代码库 > 俄罗斯方块

俄罗斯方块

技术分享

技术分享
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// <summary>
 5 /// 网格
 6 /// </summary>
 7 public class Grid : MonoBehaviour {
 8 
 9     /// <summary>
10     ///11     /// </summary>
12     public static int w = 10;
13     /// <summary>
14     ///15     /// </summary>
16     public static int h = 20;
17 
18     /// <summary>
19     /// 网格内的格子列表
20     /// </summary>
21     public static Transform[,] grid = new Transform[w, h];
22 
23     /// <summary>
24     /// 对二维向量四舍五入
25     /// </summary>
26     public static Vector2 roundVec2(Vector2 v)
27     {
28         return new Vector2(Mathf.Round(v.x), Mathf.Round(v.y));
29     }
30 
31     //保证每个被检查的位置不小于左边框,并不大于右边框,不小于最小的Y
32     public static bool insideBorder(Vector2 pos)
33     {
34         return ((int) pos.x >= 0 && 
35                 (int) pos.x < w && 
36                 (int) pos.y >= 0);
37     }
38 
39     public static bool isRowFull(int y)
40     {
41         //检查某一行的每一个单元是否为空,如果有一个是空的,那么该行还没有满
42         for (int x = 0; x < w; ++x)
43             if (grid[x, y] == null)
44                 return false;
45 
46         return true;
47     }
48 
49     public static void deleteRow(int y)
50     {
51         //删除某一行的所有数据
52         for (int x = 0; x < w; ++x)
53         {
54             Destroy(grid[x, y].gameObject);
55             grid[x, y] = null;
56         }
57     }
58 
59     public static void decreaseRow(int y)
60     {
61         //1、复制该行的数据到下一行
62         //2、清空该行数据
63         //3、视觉上的,改变原来的方块的位置 (Y + (-1))
64         for (int x = 0; x < w; ++x)
65         {
66             if (grid[x, y] != null)
67             {
68                 grid[x, y - 1] = grid[x, y];
69                 grid[x, y] = null;
70 
71                 grid[x, y - 1].position += new Vector3(0, -1, 0);
72             }
73         }
74     }
75 
76     public static void decreaseRowAbove(int y)
77     {
78         //从指定的行数开始检查该行和该行以上的位置,把上面的数据搬到下面
79         for (int i = y; i < h; i++)
80             decreaseRow(i);
81     }
82 
83     public static void deleteFullRows()
84     {
85         for (int y = 0; y < h; )
86         {
87             if (isRowFull(y))
88             {
89                 deleteRow(y);
90 
91                 decreaseRowAbove(y + 1);
92             }
93             else
94                 y++;
95         }
96     }
97 }
Grid
技术分享
  1 using UnityEngine;
  2 using System.Collections;
  3 
  4 /// <summary>
  5 /// 方块组
  6 /// </summary>
  7 public class Groups : MonoBehaviour {
  8 
  9     float lastFall = 0;
 10 
 11     void Start () {
 12 
 13         if (!isValidGridPos())
 14         {
 15             Debug.Log("GAME OVER");
 16 
 17             GameObject.Find("Canvas").GetComponent<GUIManage>().GameOver();
 18 
 19             Destroy(gameObject);
 20         }    
 21     }
 22     
 23     void Update () {
 24 
 25         //控制group左移
 26         if (Input.GetKeyDown(KeyCode.LeftArrow))
 27         {
 28             transform.position += new Vector3(-1, 0, 0);
 29 
 30             if (isValidGridPos())
 31             {
 32                 updateGrid();
 33             }
 34             else
 35             {
 36                 transform.position += new Vector3(1, 0, 0);
 37             }
 38         }
 39         //控制group右移
 40         else if (Input.GetKeyDown(KeyCode.RightArrow))
 41         {
 42             transform.position += new Vector3(1, 0, 0);
 43 
 44             if (isValidGridPos())
 45             {
 46                 updateGrid();
 47             }
 48             else
 49             {
 50                 transform.position += new Vector3(-1, 0, 0);
 51             }
 52         }
 53         //控制group旋转
 54         else if (Input.GetKeyDown(KeyCode.UpArrow))
 55         {
 56             transform.Rotate(0, 0, -90);
 57 
 58             if (isValidGridPos())
 59             {
 60                 updateGrid();
 61             }
 62             else
 63             {
 64                 transform.Rotate(0, 0, 90);
 65             }
 66         }
 67         //控制group快速掉落
 68         else if (Input.GetKeyDown(KeyCode.DownArrow) || 
 69             Time.time - lastFall >= 1f)
 70         {
 71             transform.position += new Vector3(0, -1f, 0);
 72 
 73             if (isValidGridPos())
 74             {
 75                 updateGrid();
 76             }
 77             else
 78             {
 79                 transform.position += new Vector3(0, 1, 0);
 80 
 81                 //已经到位,所以可以测试是否可以删除已经“满”的行
 82                 Grid.deleteFullRows();
 83 
 84                 FindObjectOfType<Spawner>().spawnNext();
 85                 enabled = false;
 86             }
 87 
 88             lastFall = Time.time;
 89         }
 90 
 91     }
 92 
 93     bool isValidGridPos()
 94     {
 95         foreach(Transform child in transform)
 96         {
 97             Vector2 v = Grid.roundVec2(child.position);
 98 
 99             //1、判断是否在边界之内(左、右、下方)
100             if (!Grid.insideBorder(v))
101             {
102                 return false;
103             }
104 
105             //2、现在的grid对应的格子里面是null
106             if (Grid.grid[(int)v.x, (int)v.y] != null && 
107                 Grid.grid[(int)v.x, (int)v.y].parent != transform)
108             {
109                 return false;
110             }
111         }
112 
113         return true;
114     }
115 
116     void updateGrid()
117     {
118         //上一次的数据清理,移去原来占据的格子信息
119         for (int y = 0; y < Grid.h; y++)
120             for (int x = 0; x < Grid.w; x++)
121             {
122                 if (Grid.grid[x, y] != null)
123                     if (Grid.grid[x, y].parent == transform)
124                         Grid.grid[x, y] = null;
125             }
126 
127         //加入本次的更新的位置信息
128         foreach (Transform child in transform)
129         {
130             Vector2 v = Grid.roundVec2(child.position);
131             Grid.grid[(int)v.x, (int)v.y] = child;
132         }
133     }
134 }
Groups
技术分享
 1 using UnityEngine;
 2 using System.Collections;
 3 using UnityEngine.UI;
 4 
 5 /// <summary>
 6 /// UI管理
 7 /// </summary>
 8 public class GUIManage : MonoBehaviour {
 9 
10     /// <summary>
11     /// 
12     /// </summary>
13     float time, startTime;
14     /// <summary>
15     /// 计时器文本
16     /// </summary>
17     Text timer;
18     /// <summary>
19     /// 是否结束
20     /// </summary>
21     bool isEnd = false;
22 
23     /// <summary>
24     /// 游戏结束UI
25     /// </summary>
26     public GameObject gameOverUI;
27 
28     void Start () {
29 
30         timer = GameObject.Find("Canvas/Timer").GetComponent<Text>();
31 
32         //得到游戏开始的时间(单位:秒)
33         startTime = Time.time;    
34     }
35     
36     void Update () {
37 
38         if (isEnd) return;
39 
40         //得到当前时间跟游戏开始的时间的差别 (单位:秒)
41         time = Time.time - startTime;
42 
43         //
44         int seconds = (int) (time % 60);
45         //
46         int minutes = (int) (time / 60);
47 
48         string strTime = string.Format("{0:00}:{1:00}", minutes, seconds);
49         timer.text = strTime;    
50     }
51 
52     public void GameOver()
53     {
54         gameOverUI.SetActive(true);
55 
56         isEnd = true;
57     }
58 }
GUIManage
技术分享
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 /// <summary>
 5 /// 生成方块
 6 /// </summary>
 7 public class Spawner : MonoBehaviour {
 8 
 9     /// <summary>
10     /// 方块预设列表
11     /// </summary>
12     public GameObject[] groups;
13 
14     void Start () {
15         spawnNext();
16     }
17 
18 
19     /// <summary>
20     /// 生成方块
21     /// </summary>
22     public void spawnNext()
23     {
24         //随机选择
25         int i = Random.Range(0, groups.Length);
26         GameObject ins = Instantiate(groups[i], transform.position, Quaternion.identity) as GameObject;
27     }
28 }
Spawner

视频:https://pan.baidu.com/s/1jILqE4u

项目:https://pan.baidu.com/s/1kVynXJp

俄罗斯方块