Unity制作扫雷游戏
Posted 御雪妃舞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity制作扫雷游戏相关的知识,希望对你有一定的参考价值。
曾经在网上看了一篇扫雷教程,链接如下: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);
Element.cs
using UnityEngine;
using System.Collections;
public enum MineState
Empty = 0,
Mine = 1,
Num = 2,
MaybeMine = 3
public class Element : MonoBehaviour
/// <summary>
/// current box mine state
/// </summary>
public MineState mine;
public Sprite[] emptyTextures;
public Sprite mineTexture;
public void loadTexture(int mineCount = 0)
if ((int)mine == 1)
GetComponent<SpriteRenderer>().sprite = mineTexture;
else
GetComponent<SpriteRenderer>().sprite = emptyTextures[mineCount];
public bool isCovered()
return GetComponent<SpriteRenderer>().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");
MineManager.cs
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<Element>();
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;
以上是关于Unity制作扫雷游戏的主要内容,如果未能解决你的问题,请参考以下文章
Unity3D游戏物体操作 ( 场景简介 | 添加游戏物体 | 操作游戏物体 | 选中游戏物体 | 场景显示效果缩放 | 重命名游戏物体 | 复制游戏物体 | 删除游戏物体 | 移动游戏物体 )