unity-扫雷

效果图
扫雷资源
没事自己简单做了一个扫雷,主要的点有两个,一个是地雷的随机放置;一个是八向查找地雷数;
随机地雷逻辑:

    public int GenerateRandomNumber(int min, int max)
    {
        RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
        byte[] randomNumber = new byte[4]; // 生成4字节的随机数,即32位整数
        random.GetBytes(randomNumber);
        int value = BitConverter.ToInt32(randomNumber, 0);

        // 将生成的随机数限制在指定的范围内
        return Math.Abs(value % (max - min + 1)) + min;
    }

八向查找逻辑:

    public void GetLandmineCount(int raw, int col)
    {
        HashSet<int> totalList = new HashSet<int>();
        FindEmptyAndFlag(raw, col, totalList);
    }

    private void FindEmptyAndFlag(int raw, int col, HashSet<int> totalList)
    {
        HashSet<int> tempList = new HashSet<int>();
        int index;
        int count = 0;
        for (int i = raw - 1; i <= raw + 1; i++)
        {
            for (int j = col - 1; j <= col + 1; j++)
            {
                if (i == raw && j == col) continue;

                if (IsAllow(i, j))
                {
                    index = i * this.col + j;
                    if (itemList[index].status != ClearanceItem.ItemStatus.landmine &&
                        itemList[index].curStatus == ClearanceItem.ItemStatus.normal &&
                        !(i == raw-1 && j == col-1 || i == raw-1 && j == col+1 ||
                        i== raw+1 && j == col-1 || i == raw+1 && j == col+1) &&
                        !totalList.Contains(index))
                    {
                        try
                        {
                            tempList.Add(index);
                            totalList.Add(index);
                        }
                        catch (Exception)
                        {
                            Debug.LogError("i = " + i + " j = " + j);
                            throw;
                        }
                    }
                    if (itemList[index].status == ClearanceItem.ItemStatus.landmine)
                    {
                        count++;
                    }
                }
            }
        }

        if(tempList.Count > 0)
        {
            foreach (var item in tempList)
            {
                int tempRaw = item / this.col;
                int tempCol = item % this.col;
                FindEmptyAndFlag(tempRaw, tempCol, totalList, setList);
            }
        }
        index = raw * this.col + col;
        totalList.Add(index);
        itemList[index].SetCurStutas(count);
    }
### 如何在 Unity 3D 中创建或实现扫雷游戏 #### 创建项目结构 为了构建一个基本的扫雷游戏,在Unity中可以按照如下方式设置场景和脚本: - **Grid Generation**: 需要先定义网格大小以及地雷的数量。这可以通过编写一个简单的C#脚本来完成,该脚本负责初始化地图并随机放置一定数量的地雷。 ```csharp using UnityEngine; public class MinefieldGenerator : MonoBehaviour { public int width = 10; // 地图宽度 public int height = 10; // 地图高度 public int mineCount = 10; // 地雷数目 private GameObject[,] grid; void Start() { GenerateMineField(); } void GenerateMineField() { grid = new GameObject[width, height]; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { var tileObject = Instantiate(TilePrefab); tileObject.transform.SetParent(transform); tileObject.name = $"Tile_{x}_{y}"; TileScript ts = tileObject.GetComponent<TileScript>(); if(ts != null){ ts.SetPosition(x,y); } grid[x, y] = tileObject; } } PlaceMinesRandomly(mineCount); } void PlaceMinesRandomly(int count) { System.Random r = new System.Random(); while(count > 0) { int rx = r.Next(width), ry = r.Next(height); if(grid[rx,ry].GetComponent<TileScript>().HasMine()) continue; grid[rx,ry].AddComponent<Mine>(); --count; } } } ``` 此代码片段展示了如何生成指定尺寸的地图,并随机分配地雷位置[^1]。 #### 用户交互逻辑 对于玩家点击格子的行为处理,则需另外建立相应的事件监听机制来响应用户的输入动作。当用户点击某个方块时,应该检查这个方块是否有炸弹存在;如果没有的话就显示周围有多少颗未被标记出来的邻近炸弹数目的提示信息给玩家知道。 ```csharp void OnMouseDown(){ RevealTile(); if(hasBomb){ Debug.Log("Game Over!"); GameManager.Instance.GameOver(); }else{ CalculateAdjacentBombs(); } } private void RevealTile(){ renderer.material.color = Color.gray; revealed = true; } // 计算相邻八个方向上的炸弹总数 private void CalculateAdjacentBombs(){ adjacentBombs = GetSurroundingTiles().Where(t => t.HasBomb()).Count(); textMesh.text = adjacentBombs.ToString(); } ``` 这段代码实现了单击瓷砖后的反应逻辑,包括揭示瓷砖内容物(即是否存在炸弹),并且计算周围的炸弹数量。 #### 游戏管理器设计模式的应用 考虑到整个游戏中可能涉及到多个状态之间的转换(比如开始新局、暂停/继续、结束等),采用`GameManager`类作为全局控制器是非常有帮助的做法。它能够有效地协调各个组件之间的工作流程,使得整体架构更加清晰易懂。 ```csharp public static GameManager Instance { get; private set; } void Awake(){ if(Instance == null){ Instance = this; } else Destroy(gameObject); } public void NewGame(){ foreach(Transform child in transform){ Destroy(child.gameObject); } generator.GenerateMineField(); } public void GameOver(){} ``` 上述代码提供了一个静态实例化的GameManager对象用于控制游戏的整体进程,同时也包含了重新启动一局的方法NewGame()。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值