首页 > 代码库 > 单个脚本实现扫雷
单个脚本实现扫雷
using UnityEngine;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Grid
{
public bool IsQi;//是否插旗
public bool IsLei;//是否是雷
public bool IsClicked;//是否点击了
public byte Count;//周围有几个雷
}
/// <summary>
/// 格子类
/// </summary>
public class Map2 : MonoBehaviour, IPointerClickHandler
{
#region 常量
public const int RowCount = 16;
public const int ColCount = 30;
#endregion
#region 字段
private int clickCount=0;
private Grid[,] grids = new Grid[RowCount, ColCount];
private List<Vector2> Lei;
private GameObject[,] tiles = new GameObject[RowCount, ColCount];
List<Vector2> points;//用来处理地雷坐标
private Vector2[] dirs = new Vector2[] { Vector2.up, Vector2.down, Vector2.left, Vector2.right, new Vector2(-1, 1), new Vector2(-1, -1), new Vector2(1, 1), new Vector2(1, -1) };
[SerializeField]
private Transform gridContainer;
[SerializeField]
private GameObject gridPrefab;
[SerializeField]
private Transform Panel;
[SerializeField]
private Transform Win;
[SerializeField]
private float Timer;
[SerializeField]
private int LeiNum;
bool left;
bool right;
#endregion
void Start()
{
StartGame();
}
public void StartGame()
{
LeiNum = 99;
clickCount = 0;
grids = new Grid[RowCount, ColCount];
tiles = new GameObject[RowCount, ColCount];
Lei = new List<Vector2>();
points = new List<Vector2>();
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColCount; j++)
{
grids[i, j] = new Grid();
points.Add(new Vector2(i, j));
if (GameObject.Find(i.ToString() + "_" + j.ToString()))
{
GameObject grid = GameObject.Find(i.ToString() + "_" + j.ToString());
grid.transform.GetChild(0).GetComponent<Text>().text = "";
grid.transform.GetChild(0).gameObject.SetActive(false);
grid.transform.GetChild(1).gameObject.SetActive(false);
grid.GetComponent<Image>().color = Color.white;
tiles[i, j] = grid;
}
else
{
GameObject grid = (GameObject)Instantiate(gridPrefab);
grid.transform.SetParent(gridContainer);
grid.GetComponent<RectTransform>().localScale = Vector3.one;
grid.name = i.ToString() + "_" + j.ToString();
tiles[i, j] = grid;
}
}
}
PutLei();
}
public void PutLei()
{
//随机放入地雷
while (LeiNum>0)
{
int index= Random.Range(0, points.Count );
grids[(int)points[index].x, (int)points[index].y].IsLei = true;
points.Remove(points[index]);
LeiNum--;
}
}
public void OnPointerClick(PointerEventData eventData)
{
clickCount++;
Debug.Log(clickCount);
GameObject enter = eventData.pointerEnter;
if (enter.name.Contains("_"))
{
int x = int.Parse(enter.name.Split(‘_‘)[0]);
int y = int.Parse(enter.name.Split(‘_‘)[1]);
InputKind(x, y);
Debug.Log(x + "," + y);
}
if (enter.name.Contains("+"))
{
int x = int.Parse(enter.transform.parent.name.Split(‘_‘)[0]);
int y = int.Parse(enter.transform.parent.name.Split(‘_‘)[1]);
InputKind(x, y);
Debug.Log(x + "," + y);
}
if (enter.name.Contains("*"))
{
int x = int.Parse(enter.transform.parent.parent.name.Split(‘_‘)[0]);
int y = int.Parse(enter.transform.parent.parent.name.Split(‘_‘)[1]);
InputKind(x, y);
Debug.Log(x + "," + y);
}
}
/// <summary>
/// 设定种类
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
public void InputKind(int x, int y)
{
if (left && !right)
{
left = false;//先纠正鼠标。
Debug.Log("left");
if (!tiles[x, y].transform.GetChild(1).gameObject.activeSelf)
{
GridClick(x, y);
}
}
else if (right && !left)
{
right = false;
Debug.Log("right");
Flag(x, y);
}
else if (left && right)
{
left = false;
right = false;
if (grids[x, y].IsClicked)
{
Debug.Log("double");
DiGui(x, y);
}
}
}
public void Flag(int x, int y)
{
if (!grids[x, y].IsClicked)
{
if (tiles[x, y].transform.GetChild(1).gameObject.activeSelf)
{
tiles[x, y].transform.GetChild(1).gameObject.SetActive(false);
// Debug.Log("关闭");
Lei.Remove(new Vector2(x, y));
grids[x, y].IsQi = false;
}
else
if (!tiles[x, y].transform.GetChild(1).gameObject.activeSelf)
{
tiles[x, y].transform.GetChild(1).gameObject.SetActive(true);
Lei.Add(new Vector2(x, y));
/// Debug.Log(new Vector2(x,y));
grids[x, y].IsQi = true;
}
}
}
/// <summary>
/// 格子点击
/// </summary>
/// <param name="x">The x coordinate.</param>
/// <param name="y">The y coordinate.</param>
public void GridClick(int x, int y)
{
if (!grids[x, y].IsClicked)
{
grids[x, y].IsClicked = true;
//第一次点到雷,并重启游戏数据,并点击当前位置
if (grids[x, y].IsLei&&clickCount==1) {
Start();
GridClick(x, y);
}else
if (grids[x, y].IsLei)
{
print("输了");
Colse();
return;
}
for (int i = 0; i < dirs.Length; i++)
{
int temp_x = x + (int)dirs[i].x;
int temp_y = y + (int)dirs[i].y;
//判断是否越界
if (temp_x >= 0 && temp_x < RowCount && temp_y >= 0 && temp_y < ColCount)
{
if (grids[temp_x, temp_y].IsLei)
{
grids[x, y].Count++;
}
}
}
tiles[x, y].transform.GetChild(0).gameObject.SetActive(true);
tiles[x, y].transform.GetChild(1).gameObject.SetActive(false);
tiles[x, y].GetComponent<Image>().color = Color.gray;//改变颜色
if (grids[x, y].Count > 0)
{
tiles[x, y].GetComponentInChildren<Text>().text = grids[x, y].Count.ToString();
}
else
{
DiGui(x, y);
}
}
}
/// <summary>
/// 递归
/// </summary>
/// <param name="x">The x coordinate.</param>
/// <param name="y">The y coordinate.</param>
public void DiGui(int x, int y)
{
int QiCount = 0;
for (int i = 0; i < dirs.Length; i++)
{
int temp_x = x + (int)dirs[i].x;
int temp_y = y + (int)dirs[i].y;
if (temp_x >= 0 && temp_x < RowCount && temp_y >= 0 && temp_y < ColCount)
{
if (grids[temp_x, temp_y].IsQi)
{
QiCount++;
}
}
}
for (int i = 0; i < dirs.Length; i++)
{
int temp_x = x + (int)dirs[i].x;
int temp_y = y + (int)dirs[i].y;
//判断是否越界
if (temp_x >= 0 && temp_x < RowCount && temp_y >= 0 && temp_y < ColCount)
{
//Debug.Log("开雷");
if (QiCount >= grids[x, y].Count)
{
Vector2 v1 = new Vector2(temp_x, temp_y);
//Debug.Log(v1);
if (Lei.Contains(v1)) { Debug.Log(v1 + "雷"); }
else
{
GridClick(temp_x, temp_y);
}
}
}
}
QiCount = 0;
}
public void Colse()
{
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColCount; j++)
{
if (grids[i, j].IsLei)
{
tiles[i, j].GetComponent<Image>().color = Color.black;
tiles[i, j].transform.GetChild(0).gameObject.SetActive(true);
tiles[i, j].transform.GetComponentInChildren<Text>().text = "雷";
Panel.gameObject.SetActive(true);
}
}
}
}
public void Restart()
{
Panel.gameObject.SetActive(false);
Win.gameObject.SetActive(false);
Start();
}
public void Update()
{
if (Input.GetMouseButtonDown(0))
{
left = true;
}
if (Input.GetMouseButtonDown(1))
{
right = true;
}
Check();
}
/// <summary>
/// 检测地图中所有未被点击的非雷格子
/// </summary>
private void Check()
{
int SpaceCount = 0;
for (int i = 0; i < RowCount; i++)
{
for (int j = 0; j < ColCount; j++)
{
if (!grids[i, j].IsLei && !grids[i, j].IsClicked)
{
SpaceCount++;
}
}
}
// Timer += Time.deltaTime;
if (SpaceCount == 0)
{
// Time.timeScale = 0;
Debug.Log("你赢了" + Timer);
Win.gameObject.SetActive(true);
}
}
}
单个脚本实现扫雷