unity3D制作消消乐游戏/三消算法

Unity3D消消乐制作感想及部分代码:
1:首先记录下该项目用到的部分知识——》dwteen插件,队列(Queue)的使用,对象池的使用,二维数组的使用。

消消乐的核心是算法,(寻找相邻相同物体算法,下落算法)

寻找相邻相同算法,自我理解,该算法是泛洪算法(四邻域)利用递归将所有相邻相同物体存到一个list中,泛洪算法经常用于改变图片的颜色,但是不能用递归(用递归会造成内存溢出,后期会写出来,改变图片上的相邻相同颜色的值)

 /// <summary>
    /// 执行完成后,找到了所有和点击对象相邻,且具有相同sprite的对象
    /// </summary>
    public void FillSameItemsList(Item current)
    {
      
        //如果已存在,跳过
        if (sameItemsList.Contains(current))
            return;
        //添加到列表
        sameItemsList.Add(current);
        //上下左右的Item
        Item[] tempItemList = new Item[]{
           _GetUpItem(current),_GetDownItem(current),
           _GetLeftItem(current),_GetRightItem(current)};
        for (int i = 0; i < tempItemList.Length; i++)
        {
            //如果Item不合法,跳过
            if (tempItemList[i] == null)
                continue;
            if (current.indexTag == tempItemList[i].indexTag)
            {
                FillSameItemsList(tempItemList[i]);
            }
        }
    }
   /// <summary>
    /// 获取上方Item
    /// </summary>
    /// <returns>The up item.</returns>
    /// <param name="current">Current.</param>
    private Item _GetUpItem(Item current)
    {
        int row = current.itemRow + 1;
        int column = current.itemColumn;
        if (!_CheckRCLegal(row, column))
            return null;
        return allItems[row, column];
    }

    /// <summary>
    /// 获取下方Item
    /// </summary>
    /// <returns>The down item.</returns>
    /// <param name="current">Current.</param>
    private Item _GetDownItem(Item current)
    {
        int row = current.itemRow - 1;
        int column = current.itemColumn;
        if (!_CheckRCLegal(row, column))
            return null;
        return allItems[row, column];
    }

    /// <summary>
    /// 获取左方Item
    /// </summary>
    /// <returns>The left item.</returns>
    /// <param name="current">Current.</param>
    private Item _GetLeftItem(Item current)
    {
        int row = current.itemRow;
        int column = current.itemColumn - 1;
        if (!_CheckRCLegal(row, column))
            return null;
        return allItems[row, column];
    }

    /// <summary>
    /// 获取右方Item
    /// </summary>
    /// <returns>The right item.</returns>
    /// <param name="current">Current.</param>
    private Item _GetRightItem(Item current)
    {
        int row = current.itemRow;
        int column = current.itemColumn + 1;
        if (!_CheckRCLegal(row, column))
            return null;
        return allItems[row, column];
    }

    /// <summary>
    /// 检测行列是否合法
    /// </summary>
    /// <returns><c>true</c>, if RC legal was checked, <c>false</c> otherwise.</returns>
    /// <param name="itemRow">Item row.</param>
    /// <param name="itemColumn">Item column.</param>
    public bool _CheckRCLegal(int itemRow, int itemColumn)
    {
        if (itemRow >= 0 && itemRow < rowNum && itemColumn >= 0 && itemColumn < columnNum)
            return true;
        return false;
    }

下落算法,逐列,逐个下落,利用队列存储需要下落的物体(使用队列的优点,先进先出—方便按照顺序逐个下落)

 /// <summary>
    /// 执行点击对象后的效果
    /// </summary>
    public void FillBoomList(Item current)
    {
        if (sameItemsList.Count < 3)
            return;

        boomList.AddRange(sameItemsList);
        List<Item> tempBoomList = new List<Item>();
        tempBoomList.AddRange(boomList);
        StartCoroutine(ManipulateBoomList(tempBoomList, current));
    }

    IEnumerator ManipulateBoomList(List<Item> tempBoomList, Item current)
    {

        //将所有的物体都拿出来,进行效果展示
        click_thenParent.transform.position = current.transform.position;
        for (int i = 0; i < tempBoomList.Count; i++)
        {
            tempBoomList[i].transform.parent = click_thenParent.transform;
        }
        click_thenParent.transform.DOScale(1.1f, 0.3f).onComplete = delegate
        {

            click_thenParent.transform.DOScale(0f, 0.1f).onComplete = delegate
            {
                current.transform.parent = ItemParent;
                current.transform.localScale = Vector3.one;
            };
        };

        yield return new WaitForSeconds(0.4f);
        //后期修改换成for循环
        foreach (var item in tempBoomList)
        {
            //将被消除的Item在全局列表中移除
            allItems[item.itemRow, item.itemColumn] = null;
            //回收Item:可以先不回收,这样可以进行一系列的动画操作
            SinglePool.instance.SetGameObject(item.gameObject);
            item.transform.localScale = Vector3.one;
        }

        click_thenParent.transform.localScale = Vector3.one;

        //开启下落
        yield return StartCoroutine(ItemsDrop());

    }


    /// <summary>
    /// 下落
    /// </summary>
    /// <returns>The drop.</returns>
    public IEnumerator ItemsDrop()
    {
        //逐列检测
        for (int i = 0; i < columnNum; i++)
        {
            //计数器
            int count = 0;
            //下落队列
            Queue<Item> dropQueue = new Queue<Item>();
            //逐行检测
            for (int j = 0; j < rowNum; j++)
            {
                if (allItems[j, i] != null)
                {
                    //计数
                    count++;
                    //放入队列
                    dropQueue.Enqueue(allItems[j, i]);
                }
            }
            //当一列检查完毕后可以生成物体在上面
            for (int m = 0; m < 7 - count; m++)
            {

                GameObject currentItem = SinglePool.instance.GetGameObject("Item", ItemParent);
                currentItem.transform.localScale = Vector3.one;

                Item currBtnItem = currentItem.GetComponent<Item>();
                currBtnItem.itemRow = m;
                currBtnItem.itemColumn = i;
                int index = Random.Range(0, 2);
                currBtnItem.indexTag = index;
                currBtnItem.imgBg.sprite = bgSps[index];
                currBtnItem.transform.position = InitPos[currBtnItem.itemRow, currBtnItem.itemColumn].position;
                dropQueue.Enqueue(currBtnItem);
            }

            //下落
            for (int k = 0; k < count; k++)
            {
                //获取要下落的Item
                Item current = dropQueue.Dequeue();
                //修改全局数组(原位置情况)
                allItems[current.itemRow, current.itemColumn] = null;
                //修改Item的行数
                int tempRow = current.itemRow;
                current.itemRow = k;
                //修改全局数组(填充新位置)
                allItems[current.itemRow, current.itemColumn] = current;
                //下落
                current._CurrentItemDrop(trueInitPos[current.itemRow, current.itemColumn].position);
            }
           for (int l = 0;  dropQueue.Count>0; l++)
           {
             //   print("Count: "+dropQueue.Count+"  l:"+l);
               //获取要下落的Item
               Item current = dropQueue.Dequeue();
               //修改Item的行数
               current.itemRow = 6-l;
               //修改全局数组(填充新位置)
               allItems[current.itemRow, current.itemColumn] = current;
                //下落
               // print("row:"+current.itemRow+"column:"+current.itemColumn);
               current._CurrentItemDrop(trueInitPos[current.itemRow, current.itemColumn].position);
           }

        }
        yield break;
        //  print("创建新的对象");
        // StartCoroutine(CreateNewItem());
    }

下落之前需要在每列上方生成需要的物体,这里使用的是对象池管理对象,减少了生成销毁对象的步骤(这也算是优化了游戏)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class SinglePool : MonoBehaviour
{

    //单例
    public static SinglePool instance;
    //对象池
    private Dictionary<string, List<GameObject>> pool;

    void Awake()
    {
        instance = this;
        pool = new Dictionary<string, List<GameObject>>();
    }
    /// <summary>
    /// 对象池回收物体
    /// </summary>
    /// <param name="current">被回收的不需要的对象.</param>
    public void SetGameObject(GameObject current)
    {
        //设置成非激活状态
        current.SetActive(false);
        //清空父对象
        //      current.transform.parent = null;
        //是否有该类型的对象池
        if (pool.ContainsKey(current.name))
        {
            //添加到对象池
            pool[current.name].Add(current);
        }
        else
        {
            pool[current.name] = new List<GameObject>() { current };
        }
    }
    /// <summary>
    /// 对象池获取物体
    /// </summary>
    /// <returns>The game object.</returns>
    /// <param name="objName">物体名字.</param>
    /// <param name="parent">父对象名字.</param>
    public GameObject GetGameObject(string objName, Transform parent = null)
    {
        GameObject current;
        //包含此对象池,且有对象
        string objName2 = objName + "(Clone)";
        if (pool.ContainsKey(objName2) && pool[objName2].Count > 0)
        {
            //获取对象
            //  print("获取对象次中的对象");
            current = pool[objName2][0];
            current.transform.localScale = new Vector3(1, 1, 1);
            pool[objName2].Remove(pool[objName2][0]);
        }
        else
        {
            //加载预设体
            GameObject prefab = Resources.Load<GameObject>("Prefabs/" + objName);
            //生成
            current = Instantiate(prefab) as GameObject;
        }
        //设置激活状态
        current.SetActive(true);
       
        //设置父物体
        current.transform.parent = parent;
        //返回
        return current;
    }
}

至于加分过关等代码都是简单的添加就可以了。最主要的是上面的一些代码。
对我来说,容易忘记的是下落算法的实现(这里利用的是逐个下落的方式,这也算是个很好的方法)

原工程版本2018.2.7,需要的小伙伴可以到我的资源里下载。
链接: https://pan.baidu.com/s/1EbkNjfU5V2QzntmKk8d1fA 提取码: vd3s 复制这段内容后打开百度网盘手机App,操作更方便哦
实现效果:
在这里插入图片描述

这里有一个qq群:群号:319506028,名字:Unity、AR、VR俱乐部,里面有很多技术大神,可以在群里问问题(关于unity的任何问题,不限VR AR,群名不重要),欢迎你的加入。

### 回答1: 三消游戏是一种益智休闲游戏,玩家需要通过消除相同图案的方块来完成关卡目标。在游戏中,玩家会看到一个盛满了方块的游戏界面,在这些方块中,可能会有不同的图案,例如水果、宝石或其他物品。 玩家需要通过交换相邻的方块,使得至少三个相同的方块连在一起。当这些方块连成一条直线或者横排时,它们就会消除,并在消除的同时获得分数。消除方块后,上面的方块会下落填补空缺,同时可能会形成新的连线和消除。玩家需要在有限的步数或时间内,消除特定数量的方块或达到特定得分才能过关。 箱子是三消游戏中的一种特殊元素。一些方块上可能会有箱子,这些箱子会被锁住,玩家需要通过消除它们周围的方块来解锁。当玩家成功地将所有箱子解锁并消除时,就可以通过关卡。箱子在游戏中起着重要的作用,因为它们常常会阻挡其他连线的形成,需要玩家巧妙地利用消除方块的顺序和方向,来解锁和消除这些箱子,从而达到过关的目标。 Unity是一种强大的游戏引擎,许多三消游戏也是使用Unity开发的。Unity提供了丰富的开发工具和资源,使得开发者能够轻松创建精美的游戏画面和流畅的游戏体验。借助Unity的强大功能,开发者可以有效地设计和调试三消游戏中的各种元素和特效,从而让玩家获得更好的游戏体验。 总之,三消箱子游戏是一种有趣的休闲游戏,玩家需要消除相同的方块来解锁箱子并完成关卡。Unity作为游戏开发引擎,为开发者提供了强大的开发工具和资源,使他们能够创建精美且流畅的游戏体验。 ### 回答2: 三消游戏是一种益智类游戏,玩家需要通过消除游戏画面中的方块或者球体来获得高分。通常情况下,玩家需要在有限的步数内达到特定目标,如消除特定数量的方块或者获得足够的分数。 而"箱子"是三消游戏中的一种常见元素,通常以方块的形式呈现。玩家需要通过移动箱子的位置,使相同颜色的箱子排列在一起来达到消除的效果。当一行或一列的箱子成为相同颜色的连续序列时,这些箱子就会被消除,玩家就可以获得分数。 Unity是一种广泛使用的游戏引擎,可以帮助开发者创建三消游戏。通过Unity的工具和功能,开发者可以轻松地设计游戏的界面、操作方式和游戏规则,并且可以实现一些特殊的特效效果,提升游戏的可玩性和视觉效果。 在Unity中,开发者可以使用脚本编写游戏逻辑,包括箱子的生成、移动、消除和得分等功能。同时,Unity还提供了一些内置的物理引擎和碰撞检测机制,可以使箱子的移动和消除更加真实和流畅。 总之,三消箱子游戏是一种益智类游戏,玩家需要通过移动和排列箱子来消除。Unity是一种强大的游戏引擎,可以帮助开发者轻松地创建和设计三消箱子游戏,提供丰富的工具和功能,实现游戏的逻辑、物理效果和可视化效果。 ### 回答3: 三消是一种流行的益智类游戏,是指通过消除方块或物品来达到游戏目标的一种玩法。而箱子则是一种游戏中常见的元素,可以用来堆叠、移动或隐藏其他物品。 《三消 箱子 Unity》是基于Unity引擎开发的一款具有三消和箱子元素的游戏游戏的核心目标是通过消除特定的方块或物品,解开不同关卡的谜题和难题。 在游戏中,玩家需要以逻辑和策略来规划自己的移动和消除,通过交换箱子的位置来实现相同颜色或形状的方块的匹配。一旦匹配的方块或物品达到一定数量,它们将会消失并获得分数。 游戏的关卡设置多样化,会有不同的限制和规则。有些关卡需要在有限的步数内完成目标,有些则需要在规定的时间内尽快消除方块。同时,游戏可能还添加了特殊道具或障碍物,增加了游戏的挑战性和乐趣。 《三消 箱子 Unity》在视觉效果和音效上通常会进行精心设计,使整个游戏过程更加美观和令人愉悦。游戏还可能提供多个游戏模式和难度选择,以满足不同玩家的需求和挑战。 总结来说,《三消 箱子 Unity》是一款有趣而富有挑战性的游戏,玩家需要通过消除方块或物品,解开谜题和难题。这款游戏通过使用Unity引擎并结合三消和箱子元素,为玩家带来了独特的游戏体验。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yffgamestart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值