曾经在网上看了一篇扫雷教程,链接如下:https://noobtuts.com/unity/2d-minesweeper-game
但是照着做出来有点问题,后来自己尝试的做了一个,效果如图:
主要有三个代码,一个是排序代码,一个是管理脚本,还有一个是子物体属性脚本,脚本内容如下:
GridTransform.cs
using UnityEngine;
using System.Collections;
public class GridTransform : MonoBehaviour
{
//排序的列数
public int column = 1;
//间距的宽和高
public float space_w;
public float space_h;
//组件对象的宽和高
public float width;
public float Height;
//排序对象的数目
public int itemNumber;
public bool Direction;
//字段封装实时排序
public bool repositionNow
{
set
{
_repositionNow = value;
if (value)
{
Sort();
_repositionNow = false;
}
}
get
{
return _repositionNow;
}
}
private bool _repositionNow;
//排序方法
void Sort()
{
itemNumber = transform.childCount; ;
for (int i = 0; i < itemNumber; i++)
{
transform.GetChild(i).localPosition = new Vector3((width + space_w) * ((i) % (column)), (Direction?1:-1)*((i) / column) * (Height + space_h), 0);
}
}
}
using UnityEngine;
using System.Collections;
public enum MineState
{
Empty = 0,
Mine = 1,
Num = 2,
MaybeMine = 3
}
public class Element : MonoBehaviour
{
///
/// current box mine state
///
public MineState mine;
public Sprite[] emptyTextures;
public Sprite mineTexture;
public void loadTexture(int mineCount = 0)
{
if ((int)mine == 1)
GetComponent().sprite = mineTexture;
else
GetComponent().sprite = emptyTextures[mineCount];
}
public bool isCovered()
{
return GetComponent().sprite.texture.name == "default";
}
void OnMouseUpAsButton()
{
Debug.Log(transform.localPosition.x + " " + transform.localPosition.y+" "+mine);
if ((int)mine == 1)
{
MineManager.Instance.uncoverMines();
print("you lose");
}
else
{
int x = (int)transform.localPosition.x;
int y = (int)transform.localPosition.y;
loadTexture(MineManager.Instance.MineCount(x, y));
MineManager.Instance.FFuncover(x, y, new bool[MineManager.Instance.width, MineManager.Instance.height]);
if (MineManager.Instance.isFinished())
{
print("you win");
}
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class MineManager : MonoBehaviour
{
public GameObject elementPrefab;
public GridTransform grid;
public int width;
public int height;
public Element[,] elements;
public int mineNumber;
public ArrayList MineLocation;
public static MineManager Instance;
// Use this for initialization
void Start()
{
Instance = this;
elements = new Element[width, height];
MineLocation = new ArrayList();
Init();
}
void Init()
{
//create element
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
elements[i, j] = CreateElement();
elements[i, j].mine = MineState.Empty;
}
}
//reset position
grid.repositionNow = true;
//random mine in the current elements
for (int n = 0; n < mineNumber; n++)
{
int k = Random.Range(0, width);
int m = Random.Range(0, height);
Vector2 temp = new Vector2(k, m);
if (MineLocation.Contains(temp))
{
n--;
continue;
}
elements[k, m].mine = MineState.Mine;
Debug.Log(elements[k, m].mine);
//elements[k, m].loadTexture();
var c = new Vector2(k, m);
Debug.Log(c);
MineLocation.Add(c);
}
//set numbers near mine
foreach (var item in MineLocation)
{
Vector2 t = (Vector2)item;
int x = (int)t.x;
int y = (int)t.y;
JudegeMinesNear(x - 1, y + 1);
JudegeMinesNear(x, y + 1);
JudegeMinesNear(x + 1, y + 1);
JudegeMinesNear(x - 1, y);
JudegeMinesNear(x + 1, y);
JudegeMinesNear(x - 1, y - 1);
JudegeMinesNear(x, y - 1);
JudegeMinesNear(x + 1, y - 1);
}
}
// Find out if a mine is at the coordinates
public bool mineAt(int x, int y)
{
// Coordinates in range? Then check for mine.
if (x >= 0 && y >= 0 && x < width && y < height)
return (int)elements[x, y].mine == 1;
return false;
}
public bool IsInclude(int x, int y)
{
if (x >= 0 && y >= 0 && x < width && y < height)
return true;
return false;
}
public void JudegeMinesNear(int x, int y)
{
if (IsInclude(x, y) == false)
return;
if ((int)elements[x, y].mine != 1)
{
elements[x, y].mine = MineState.Num;
//elements[x, y].loadTexture(MineCount(x, y));
}
}
// Count adjacent mines for an element
public int MineCount(int x, int y)
{
int count = 0;
if (mineAt(x, y + 1)) ++count; // top
if (mineAt(x + 1, y + 1)) ++count; // top-right
if (mineAt(x + 1, y)) ++count; // right
if (mineAt(x + 1, y - 1)) ++count; // bottom-right
if (mineAt(x, y - 1)) ++count; // bottom
if (mineAt(x - 1, y - 1)) ++count; // bottom-left
if (mineAt(x - 1, y)) ++count; // left
if (mineAt(x - 1, y + 1)) ++count; // top-left
return count;
}
// Flood Fill empty elements
public void FFuncover(int x, int y, bool[,] visited)
{
// Coordinates in Range?
if (IsInclude(x,y))
{
// visited already?
if (visited[x, y])
return;
// uncover element
elements[x, y].loadTexture(MineCount(x, y));
Debug.Log(" " + x + " " + y);
// close to a mine? then no more work needed here
if (MineCount(x, y) > 0)
return;
// set visited flag
visited[x, y] = true;
// recursion
FFuncover(x - 1, y + 1, visited);
FFuncover(x, y + 1, visited);
FFuncover(x + 1, y + 1, visited);
FFuncover(x - 1, y, visited);
FFuncover(x + 1, y, visited);
FFuncover(x - 1, y - 1, visited);
FFuncover(x, y - 1, visited);
FFuncover(x + 1, y - 1, visited);
Debug.Log("----------------------------------------");
}
}
// Uncover all Mines
public void uncoverMines()
{
foreach (Element elem in elements)
if (elem.mine == MineState.Mine)
elem.loadTexture(0);
}
Element CreateElement()
{
GameObject temp = Instantiate(elementPrefab) as GameObject;
temp.transform.parent = grid.transform;
temp.transform.position = Vector3.zero;
return temp.GetComponent();
}
public bool isFinished()
{
// Try to find a covered element that is no mine
foreach (Element elem in elements)
if (elem.isCovered() && (int)elem.mine != 1)
return false;
// There are none => all are mines => game won.
return true;
}
}
工程下载