在Untiy中实现扫雷游戏,并且打包Apk

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/U3DJueQi/article/details/83001227

前言:《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。

在实现扫雷的主要逻辑中,主要的难点:

(1)如何检测以一个对象为中心的八个方向上面的雷的个数。

(2)检测如果是八个方向上面都没有雷的存在,应该如何去处理。

在这里主要使用的是一个递归调用,网上很多说是泛洪算法,不管如何说,就是一个递归调用而已。

在下面我会附上扫雷完整游戏的一个Dmeo,代码都在,感兴趣的可以下载了解一下。

下面主要说一下扫雷游戏的主要制作部分,

第一部分,生成一个网格,这里提供了三种的难度,对应的网格分别是

简单   9*9      30(雷l)

中度  12*9     40

难     14*9      50三种规格,实现方法都是一样的。

void Sort()
    {
        list = new List<GameObject>();
        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < column; j++)
            {
                GameObject temp = Instantiate(prefab);
                list.Add(temp);
                if (parent!=null)
                {
                    temp.transform.SetParent(parent);
                    ElementCon element = temp.GetComponent<ElementCon>();
                    element._X = i;
                    element._Y = j;
                    value = Random.Range(0.0f,1.0f);
                    if (value <= 0.5f&& NumberOfMine>0)
                    {
                        element.state = MineState.Mine;//状态为雷
                        NumberOfMine--;
                    }
                    else
                    {
                        element.state = MineState.NotMine;//状态不是雷
                    }
                    //通过行号,列号,以及每个块的大小,计算出,每个块的位置坐标
                    temp.transform.localPosition = new Vector3(space_W + j * height,                 
                    space_H + i * width, 0);
                }
            }
        }
    }

第二部分,就是鼠标点击每个块后的检测问题

思路如下:

以鼠标点击的对象为中心,开始检测该位置,上,左上,右上,左下,右下,左,右,位置的项(顺序无所谓);

三种检测结果:

(1)是雷;

(2)周围有雷;

(3)为空。

然后,我们需要对三种情况分别进行处理,第一,第二种比较简单,这里我们说一下第三种情况

如果检测到该中心位置为空,则我们需要分别把八个方向上的对象分别作为,检测的中心来重复上面的步骤。

主要代码如下:

    /// <summary>
    /// 进行检测,把需要检测的对象传递过来
    /// </summary>
    /// <param name="curObj"></param>
    public void CheckMine(GameObject curObj)
    {
        if (curObj!=null)
        {
            SetCurState(curObj.GetComponent<ElementCon>());
        }
    }
    /// <summary>
    /// 进行检测设置当前块的状态
    /// </summary>
    public void SetCurState(ElementCon elementCon)
    {
        JudgeMinesNear(elementCon._X + 1, elementCon._Y, elementCon);//右
        JudgeMinesNear(elementCon._X - 1, elementCon._Y, elementCon);//左
        JudgeMinesNear(elementCon._X, elementCon._Y + 1, elementCon);//上
        JudgeMinesNear(elementCon._X, elementCon._Y - 1, elementCon);//下
        JudgeMinesNear(elementCon._X - 1, elementCon._Y + 1, elementCon);//左上
        JudgeMinesNear(elementCon._X - 1, elementCon._Y - 1, elementCon);//左下
        JudgeMinesNear(elementCon._X + 1, elementCon._Y + 1, elementCon);//右上
        JudgeMinesNear(elementCon._X + 1, elementCon._Y - 1, elementCon);//右下
        ContineCheck(elementCon);
    }
    /// <summary>
    /// 用于检测本雷附件雷的个数
    /// </summary>
    /// <param name="x"></param>
    /// <param name="y"></param>
    public void JudgeMinesNear(int x, int y, ElementCon elementCon)
    {
        //防止对象不存在
        for (int i = 0; i < GridTrans.Instance.list.Count; i++)
        {
            if (list[i].GetComponent<ElementCon>()._X 
                ==x&&list[i].GetComponent<ElementCon>()._Y == y)
            {
                if (list[i].GetComponent<ElementCon>().state == MineState.Mine)
                {
                    elementCon.mineCount += 1;
                }
            }
        }
    }
    /// <summary>
    /// 因为牵扯到当前按钮附件雷的数量为0的情况,所以需要继续进行检测
    /// </summary>
    public void ContineCheck(ElementCon elementCon)
    {
        if (elementCon.mineCount == 0)
        {
            elementCon.state = MineState.Empty;
            elementCon.ShowTexture(elementCon.state);
            CheckIsOver();

            //检测为空的话,把八个对象分别作为检测的中心
            CheckMine(CurCheckCenter(elementCon._X + 1, elementCon._Y, 
            elementCon));//右为中心
            CheckMine(CurCheckCenter(elementCon._X - 1, elementCon._Y, 
            elementCon));//左为中心
            CheckMine(CurCheckCenter(elementCon._X, elementCon._Y + 1, 
            elementCon));//上为中心
            CheckMine(CurCheckCenter(elementCon._X, elementCon._Y - 1, 
            elementCon));//下为中心
            CheckMine(CurCheckCenter(elementCon._X - 1, elementCon._Y + 1, 
            elementCon));//左上为中心
            CheckMine(CurCheckCenter(elementCon._X - 1, elementCon._Y - 1, 
            elementCon));//左下为中心
            CheckMine(CurCheckCenter(elementCon._X + 1, elementCon._Y + 1, 
            elementCon));//右上为中心
            CheckMine(CurCheckCenter(elementCon._X + 1, elementCon._Y - 1, 
            elementCon));//右下为中心
        }
        else
        {
            elementCon.state = MineState.Num;
            elementCon.ShowTexture(elementCon.state);
            CheckIsOver();
        }

    }
    /// <summary>
    /// 获取下一个检测中心
    /// </summary>
    /// <param name="x">位置索引坐标X</param>
    /// <param name="y">位置索引Y</param>
    /// <param name="element">上一个空元素</param>
    /// <returns></returns>
    public GameObject CurCheckCenter(int x,int y,ElementCon element)
    {
        GameObject temp = null;
         //防止对象不存在
        for (int i = 0; i < list.Count; i++)
        {
            if (list[i].GetComponent<ElementCon>()._X == x && 
                list[i].GetComponent<ElementCon>()._Y == y)
            {
                if (list[i].GetComponent<ElementCon>().state==MineState.Mine|| 
                  list[i].GetComponent<ElementCon>().state == MineState.NotMine)
                {
                    temp = list[i];
                }
            }
        }
        return temp;
    }

链接地址:https://pan.baidu.com/s/16Nf7kb2ytRy8dsklMijefg 密码:4t28

猜你喜欢

转载自blog.csdn.net/U3DJueQi/article/details/83001227