• Unity3D_(游戏)甜品消消乐02_游戏核心算法


    甜品消消乐01_游戏基础界面  传送门

    甜品消消乐02_游戏核心算法  传送门

    甜品消消乐03_游戏UI设计     传送门

      GameManager脚本上修改Fill Time可以改变消消乐移动速度 

    实现过程

    甜甜圈相邻与交换

      给甜甜圈添加Box Colliderz碰撞组件

      判断甜品是否相邻

        private bool IsFriend(GameSweet sweet1 , GameSweet sweet2)
        {
            return (sweet1.X == sweet2.X && Mathf.Abs(sweet1.Y-sweet2.Y)==1)||(sweet1.Y==sweet2.Y&&Mathf.Abs(sweet1.X-sweet2.X)==1);
            
        }

      交换两个甜品的方法

     private void ExchangeSweets(GameSweet sweet1,GameSweet sweet2)
        {
            if(sweet1.CanMove()&&sweet2.CanMove())
            {
                sweets[sweet1.X, sweet1.Y] = sweet2;
                sweets[sweet2.X, sweet2.Y] = sweet1;
    
                int tempX = sweet1.X;
                int tempY = sweet1.Y;
    
    
                sweet1.MovedComponet.Move(sweet2.X, sweet2.Y, fillTime);
                sweet2.MovedComponet.Move(tempX, tempY, fillTime);
            }
        }

      定义要交换的两个甜品

        private GameSweet pressedSweet;
        private GameSweet enteredSweet;

      注册鼠标按下事件

        //鼠标点击
        private void OnMouseEnter()
        {
            gameManager.EnterSweet(this);
        }
    
        //鼠标按下
        private void OnMouseDown()
        {
            gameManager.PressSweet(this);
        }
    
        //鼠标抬起
        private void OnMouseUp()
        {
            gameManager.ReleaseSweet();
        }
    
    
       public void PressSweet(GameSweet sweet)
        {
            pressedSweet = sweet;
    
        }
    
        public void EnterSweet(GameSweet sweet)
        {
            enteredSweet = sweet;
        }
    
        public void ReleaseSweet()
        {
            if (IsFriend(pressedSweet, enteredSweet))
            {
                ExchangeSweets(pressedSweet, enteredSweet);
            }
        }

    添加清除动画

       

      Create->Animation创建一个新的动画,将动画拖动到NormalSweetPrefab预制体上

      打开动画编辑器Window->Animator

      动画缩放第一个位置

      动画缩放第二个位置

      动画缩放第三个位置

      动画缩放第四个位置

      动画播放器中添加Color属性,在1:00下设置a(透明度)为0

     直线匹配的核心算法

      直线匹配检测方法

     public List<GameSweet> MatchSweets(GameSweet sweet,int newX,int newY)
        {
            if (sweet.CanColor())
            {
                ColorSweet.ColorType color = sweet.ColorComponet.Color;
                List<GameSweet> matchRowSweets = new List<GameSweet>();
                List<GameSweet> matchLineSweets = new List<GameSweet>();
                List<GameSweet> finishedMatchSweets = new List<GameSweet>();
    
                //行匹配
                matchRowSweets.Add(sweet);
    
                //i=0代表往左,i=1代表往右
                for(int i = 0; i <= 1; i++)
                {
                    for(int xDistance = 1; xDistance < xColumn; xDistance++)
                    {
                        int x;
                        if (i == 0)
                        {
                            x = newX - xDistance;
                        }
                        else
                        {
                            x = newX + xDistance;
                        }
                        if (x < 0 || x >= xColumn)
                        {
                            break;
                        }
                        if (sweets[x, newY].CanColor() && sweets[x, newY].ColorComponet.Color == color)
                        {
                            matchRowSweets.Add(sweets[x,newY]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                //检查一下当前行遍历列表中的元素是否大于3
                if (matchRowSweets.Count >= 3)
                {
                    for(int i = 0; i < matchRowSweets.Count; i++)
                    {
                        finishedMatchSweets.Add(matchRowSweets[i]);
                    }
                }
    
                if (finishedMatchSweets.Count >= 3)
                {
                    return finishedMatchSweets;
                }
    
                //列匹配
                matchLineSweets.Add(sweet);
    
                //i=0代表往左,i=1代表往右
                for (int i = 0; i <= 1; i++)
                {
                    for (int yDistance = 1; yDistance < yRow; yDistance++)
                    {
                        int y;
                        if (i == 0)
                        {
                            y = newY - yDistance;
                        }
                        else
                        {
                            y = newY + yDistance;
                        }
                        if (y < 0 || y >= yRow)
                        {
                            break;
                        }
                        if (sweets[newX, y].CanColor() && sweets[newX, y].ColorComponet.Color == color)
                        {
                            matchLineSweets.Add(sweets[newX, y]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                //检查一下当前行遍历列表中的元素是否大于3
                if (matchLineSweets.Count >= 3)
                {
                    for (int i = 0; i < matchLineSweets.Count; i++)
                    {
                        finishedMatchSweets.Add(matchLineSweets[i]);
                    }
                }
    
                if (finishedMatchSweets.Count >= 3)
                {
                    return finishedMatchSweets;
                }
    
            }
            return null;
        }

      满足交换条件时交换甜品

        private void ExchangeSweets(GameSweet sweet1, GameSweet sweet2)
        {
            if (sweet1.CanMove() && sweet2.CanMove())
            {
                sweets[sweet1.X, sweet1.Y] = sweet2;
                sweets[sweet2.X, sweet2.Y] = sweet1;
    
                if (MatchSweets(sweet1, sweet2.X, sweet2.Y) != null || MatchSweets(sweet2, sweet1.X, sweet1.Y) != null)
                {
                    int tempX = sweet1.X;
                    int tempY = sweet1.Y;
    
    
                    sweet1.MovedComponet.Move(sweet2.X, sweet2.Y, fillTime);
                    sweet2.MovedComponet.Move(tempX, tempY, fillTime);
                }
                else 
                {
                    sweets[sweet1.X, sweet1.Y] = sweet1;
                    sweets[sweet2.X, sweet2.Y] = sweet2;
                }
    
            }
        }

      当交换完成时能出现匹配个数大于等于三则允许交换,否者不能交换

      T型匹配和L型匹配

      

     public List<GameSweet> MatchSweets(GameSweet sweet, int newX, int newY)
        {
            if (sweet.CanColor())
            {
                ColorSweet.ColorType color = sweet.ColorComponet.Color;
                List<GameSweet> matchRowSweets = new List<GameSweet>();
                List<GameSweet> matchLineSweets = new List<GameSweet>();
                List<GameSweet> finishedMatchingSweets = new List<GameSweet>();
    
                //行匹配
                matchRowSweets.Add(sweet);
    
                //i=0代表往左,i=1代表往右
                for (int i = 0; i <= 1; i++)
                {
                    for (int xDistance = 1; xDistance < xColumn; xDistance++)
                    {
                        int x;
                        if (i == 0)
                        {
                            x = newX - xDistance;
                        }
                        else
                        {
                            x = newX + xDistance;
                        }
                        if (x < 0 || x >= xColumn)
                        {
                            break;
                        }
    
                        if (sweets[x, newY].CanColor() && sweets[x, newY].ColorComponet.Color == color)
                        {
                            matchRowSweets.Add(sweets[x, newY]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                if (matchRowSweets.Count >= 3)
                {
                    for (int i = 0; i < matchRowSweets.Count; i++)
                    {
                        finishedMatchingSweets.Add(matchRowSweets[i]);
                    }
                }
    
                //L T型匹配
                //检查一下当前行遍历列表中的元素数量是否大于3
                if (matchRowSweets.Count >= 3)
                {
                    for (int i = 0; i < matchRowSweets.Count; i++)
                    {
                        //行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
                        // 0代表上方 1代表下方
                        for (int j = 0; j <= 1; j++)
                        {
                            for (int yDistance = 1; yDistance < yRow; yDistance++)
                            {
                                int y;
                                if (j == 0)
                                {
                                    y = newY - yDistance;
                                }
                                else
                                {
                                    y = newY + yDistance;
                                }
                                if (y < 0 || y >= yRow)
                                {
                                    break;
                                }
    
                                if (sweets[matchRowSweets[i].X, y].CanColor() && sweets[matchRowSweets[i].X, y].ColorComponet.Color == color)
                                {
                                    matchLineSweets.Add(sweets[matchRowSweets[i].X, y]);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
    
                        if (matchLineSweets.Count < 2)
                        {
                            matchLineSweets.Clear();
                        }
                        else
                        {
                            for (int j = 0; j < matchLineSweets.Count; j++)
                            {
                                finishedMatchingSweets.Add(matchLineSweets[j]);
                            }
                            break;
                        }
                    }
                }
    
                if (finishedMatchingSweets.Count >= 3)
                {
                    return finishedMatchingSweets;
                }
    
                matchRowSweets.Clear();
                matchLineSweets.Clear();
    
                matchLineSweets.Add(sweet);
    
                //列匹配
    
                //i=0代表往左,i=1代表往右
                for (int i = 0; i <= 1; i++)
                {
                    for (int yDistance = 1; yDistance < yRow; yDistance++)
                    {
                        int y;
                        if (i == 0)
                        {
                            y = newY - yDistance;
                        }
                        else
                        {
                            y = newY + yDistance;
                        }
                        if (y < 0 || y >= yRow)
                        {
                            break;
                        }
    
                        if (sweets[newX, y].CanColor() && sweets[newX, y].ColorComponet.Color == color)
                        {
                            matchLineSweets.Add(sweets[newX, y]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                if (matchLineSweets.Count >= 3)
                {
                    for (int i = 0; i < matchLineSweets.Count; i++)
                    {
                        finishedMatchingSweets.Add(matchLineSweets[i]);
                    }
                }
    
                //L T型匹配
                //检查一下当前行遍历列表中的元素数量是否大于3
                if (matchLineSweets.Count >= 3)
                {
                    for (int i = 0; i < matchLineSweets.Count; i++)
                    {
                        //行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
                        // 0代表上方 1代表下方
                        for (int j = 0; j <= 1; j++)
                        {
                            for (int xDistance = 1; xDistance < xColumn; xDistance++)
                            {
                                int x;
                                if (j == 0)
                                {
                                    x = newY - xDistance;
                                }
                                else
                                {
                                    x = newY + xDistance;
                                }
                                if (x < 0 || x >= xColumn)
                                {
                                    break;
                                }
    
                                if (sweets[x, matchLineSweets[i].Y].CanColor() && sweets[x, matchLineSweets[i].Y].ColorComponet.Color == color)
                                {
                                    matchRowSweets.Add(sweets[x, matchLineSweets[i].Y]);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
    
                        if (matchRowSweets.Count < 2)
                        {
                            matchRowSweets.Clear();
                        }
                        else
                        {
                            for (int j = 0; j < matchRowSweets.Count; j++)
                            {
                                finishedMatchingSweets.Add(matchRowSweets[j]);
                            }
                            break;
                        }
                    }
                }
    
                if (finishedMatchingSweets.Count >= 3)
                {
                    return finishedMatchingSweets;
                }
            }
    
            return null;
        }
    匹配方法

    消除脚本

      添加ClearedSweet脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ClearedSweet : MonoBehaviour {
    
        //清除脚本的动画
        public AnimationClip clearAnimation;
    
        private bool isClearing;
    
        public bool IsClearing
        {
            get
            {
                return isClearing;
            }
        }
    
        //为了方便后期做拓展,设置成protected
        protected GameSweet sweet;
    
        public virtual void Clear()
        {
            isClearing = true;
            StartCoroutine(ClearCoroutine());
        }
    
        private IEnumerator ClearCoroutine()
        {
            Animator animator = GetComponent<Animator>();
    
            if (animator!=null)
            {
                animator.Play(clearAnimation.name);
                //玩家得分,播放清除声音
                yield return new WaitForSeconds(clearAnimation.length);
                Destroy(gameObject);
            }
        }
    
    }
    ClearedSweet.cs

      清除脚本的动画

     public AnimationClip clearAnimation;

      协成中清楚甜甜圈

      public virtual void Clear()
       {
            isClearing = true;
            StartCoroutine(ClearCoroutine());
        }
    
        private IEnumerator ClearCoroutine()
        {
            Animator animator = GetComponent<Animator>();
    
            if (animator!=null)
            {
                animator.Play(clearAnimation.name);
                //玩家得分,播放清除声音
                yield return new WaitForSeconds(clearAnimation.length);
                Destroy(gameObject);
            }
        }

    消除甜品

      获得清除脚本

        public ClearedSweet ClearedCompent
        {
            get
            {
                return clearedCompent;
            }
        }

      判断是否可以清除

        public bool CanClear()
        {
            return clearedCompent != null;
        }

      注册清除甜甜圈方法

        private void Awake()
        {
            movedComponet = GetComponent<MovedSweet>();
            coloredCompent = GetComponent<ColorSweet>();
            clearedCompent = GetComponent<ClearedSweet>();
        }

      NormalSweetPrefab预制体上添加ClearedSweet脚本

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ClearedSweet : MonoBehaviour {
    
        //清除脚本的动画
        public AnimationClip clearAnimation;
    
        private bool isClearing;
    
        public bool IsClearing
        {
            get
            {
                return isClearing;
            }
        }
    
        //为了方便后期做拓展,设置成protected
        protected GameSweet sweet;
    
        public virtual void Clear()
        {
            isClearing = true;
            StartCoroutine(ClearCoroutine());
        }
    
        private IEnumerator ClearCoroutine()
        {
            Animator animator = GetComponent<Animator>();
    
            if (animator!=null)
            {
                animator.Play(clearAnimation.name);
                //玩家得分,播放清除声音
                yield return new WaitForSeconds(clearAnimation.length);
                Destroy(gameObject);
            }
        }
    
    }
    ClearedSweet

       清除方法

        public bool ClearSweet(int x,int y)
        {
            if (sweets[x, y].CanClear()&&!sweets[x,y].ClearedCompent.IsClearing)
            {
                sweets[x, y].ClearedCompent.Clear();
                CreateNewSweet(x,y,SweetsType.EMPTY);
    
                return true;
            }
            return false;
        }

      清除全部完成匹配的甜品

    private bool ClearAllMatchedSweet()
        {
            bool needRefill = false;
    
            for(int y = 0; y < yRow; y++)
            {
                for (int x=0;x<xColumn;x++)
                {
                    if (sweets[x, y].CanClear())
                    {
                         List<GameSweet> matchList = MatchSweets(sweets[x,y],x,y);
    
                        if (matchList != null)
                        {
                            for (int i=0;i<matchList.Count;i++)
                            {
                                if (ClearSweet(matchList[i].X, matchList[i].Y))
                                {
                                    needRefill = true;
                                }
                            }
                        }
                    }
                }
            }
            return needRefill;
        }
     private void ExchangeSweets(GameSweet sweet1, GameSweet sweet2)
        {
            if (sweet1.CanMove() && sweet2.CanMove())
            {
                sweets[sweet1.X, sweet1.Y] = sweet2;
                sweets[sweet2.X, sweet2.Y] = sweet1;
    
                if (MatchSweets(sweet1, sweet2.X, sweet2.Y) != null || MatchSweets(sweet2, sweet1.X, sweet1.Y) != null)
                {
                    int tempX = sweet1.X;
                    int tempY = sweet1.Y;
    
    
                    sweet1.MovedComponet.Move(sweet2.X, sweet2.Y, fillTime);
                    sweet2.MovedComponet.Move(tempX, tempY, fillTime);
    
                    ClearAllMatchedSweet();
                }
                else 
                {
                    sweets[sweet1.X, sweet1.Y] = sweet1;
                    sweets[sweet2.X, sweet2.Y] = sweet2;
                }
    
            }
        }

       出现问题:

      1)初始游戏时甜品连接个数为三个的时候未进行消除

      2)  消除完三个甜品时两侧甜品未进行填充

      解决第1个问题_填充甜品的方法

     public IEnumerator AllFill()
        {
            bool needRefill = true;
    
            while(needRefill)
            {
                //完成上次填充动画
                yield return new WaitForSeconds(fillTime);
                while (Fill())
                {
                    yield return new WaitForSeconds(fillTime);
                }
    
                //清除所有我们意见匹配好的甜品
                needRefill = ClearAllMatchedSweet();
            }
    
        }

      解决第2个问题_交换两个甜品

     if (MatchSweets(sweet1, sweet2.X, sweet2.Y) != null || MatchSweets(sweet2, sweet1.X, sweet1.Y) != null)
                {
                    int tempX = sweet1.X;
                    int tempY = sweet1.Y;
    
    
                    sweet1.MovedComponet.Move(sweet2.X, sweet2.Y, fillTime);
                    sweet2.MovedComponet.Move(tempX, tempY, fillTime);
    
                    ClearAllMatchedSweet();
                    //消除甜品时两侧甜品进行填充
                    StartCoroutine(AllFill());
    
                }
                else 
                {
                    sweets[sweet1.X, sweet1.Y] = sweet1;
                    sweets[sweet2.X, sweet2.Y] = sweet2;
                }

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class MovedSweet : MonoBehaviour {
    
        private GameSweet sweet;
    
        private IEnumerator moveCoroutine;
    
        private void Awake()
        {
            sweet = GetComponent<GameSweet>();
        }
    
        //开启或者结束一个协成
        public void Move(int newX,int newY,float time)
        {
            if(moveCoroutine!=null)
            {
                StopCoroutine(moveCoroutine);
            }
    
            moveCoroutine = MoveCoroutine(newX,newY,time);
            StartCoroutine(moveCoroutine);
        }
    
        //负责移动的协成
        private IEnumerator MoveCoroutine(int newX,int newY,float time)
        {
            sweet.X = newX;
            sweet.Y = newY;
    
            //每一帧移动一点点
            Vector3 startPos = transform.position;
            Vector3 endPos = sweet.gameManager.CorrectPosition(newX,newY);
    
            for(float t=0;t<time;t+=Time.deltaTime)
            {
                sweet.transform.position = Vector3.Lerp(startPos,endPos,t/time);
                yield return 0;
            }
    
            sweet.transform.position = endPos;
        }
    }
    MovedSweet.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ClearedSweet : MonoBehaviour {
    
        //清除脚本的动画
        public AnimationClip clearAnimation;
    
        private bool isClearing;
    
        public bool IsClearing
        {
            get
            {
                return isClearing;
            }
        }
    
        //为了方便后期做拓展,设置成protected
        protected GameSweet sweet;
    
        public virtual void Clear()
        {
            isClearing = true;
            StartCoroutine(ClearCoroutine());
        }
    
        private IEnumerator ClearCoroutine()
        {
            Animator animator = GetComponent<Animator>();
    
            if (animator!=null)
            {
                animator.Play(clearAnimation.name);
                //玩家得分,播放清除声音
                yield return new WaitForSeconds(clearAnimation.length);
                Destroy(gameObject);
            }
        }
    
    }
    ClearedSweet.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class ColorSweet : MonoBehaviour {
    
        public enum ColorType
        {
            YELLOW,
            PUPLE,
            RED,
            BLUE,
            GREEN,
            PNGK,
            ANY,
            COUNT
        }
    
        [System.Serializable]
        public struct ColorSprite
        {
            public ColorType color;
            public Sprite sprite;
        }
    
        public ColorSprite[] ColorSprites;
    
        private Dictionary<ColorType, Sprite> colorSpriteDict;
    
        private SpriteRenderer sprite;
    
        public int NumColors
        {
            get{ return ColorSprites.Length; }
        }
    
        public ColorType Color
        {
            get
            {
                return color;
            }
    
            set
            {
                SetColor(value);
            }
        }
    
        private ColorType color;
    
    
    
        public void Awake()
        {
            sprite = transform.Find("Sweet").GetComponent<SpriteRenderer>();
    
            colorSpriteDict = new Dictionary<ColorType, Sprite>();
    
            for(int i = 0; i < ColorSprites.Length; i++)
            {
                if (!colorSpriteDict.ContainsKey(ColorSprites[i].color))
                {
                    colorSpriteDict.Add(ColorSprites[i].color,ColorSprites[i].sprite);
                }
            }
        }
    
        public void SetColor(ColorType newColor)
        {
            color = newColor;
            if (colorSpriteDict.ContainsKey(newColor))
            {
                sprite.sprite = colorSpriteDict[newColor];
            }
        }
    
    
    }
    ColorSweet.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class GameSweet : MonoBehaviour {
    
        private int x;
        private int y;
        public int X
        {
            get
            {
                return x;
            }
    
            set
            {
                if (CanMove())
                {
                    x = value;
                }
            }
        }
        public int Y
        {
            get
            {
                return y;
            }
    
            set
            {
                if (CanMove())
                {
                    y = value;
                }
            }
        }
    
        private GameManager.SweetsType type;
        public GameManager.SweetsType Type
        {
            get
            {
                return type;
            }
        }
    
    
        [HideInInspector]
        public GameManager gameManager;
    
        public MovedSweet MovedComponet
        {
            get
            {
                return movedComponet;
            }
        }
        private MovedSweet movedComponet;
    
    
        public ColorSweet ColorComponet
        {
            get
            {
                return coloredCompent;
            }
        }
    
        public ClearedSweet ClearedCompent
        {
            get
            {
                return clearedCompent;
            }
        }
    
        private ColorSweet coloredCompent;
    
        private ClearedSweet clearedCompent;
    
    
        //判断甜品是否可以移动
        public bool CanMove()
        {
            return movedComponet != null;
        }
    
        //判断是否可以着色
        public bool CanColor()
        {
            return coloredCompent != null;
        }
    
        //判断是否可以清除
        public bool CanClear()
        {
            return clearedCompent != null;
        }
    
        private void Awake()
        {
            movedComponet = GetComponent<MovedSweet>();
            coloredCompent = GetComponent<ColorSweet>();
            clearedCompent = GetComponent<ClearedSweet>();
        }
    
        public void Init(int _x,int _y,GameManager _gameManager,GameManager.SweetsType _type)
        {
            x = _x;
            y = _y;
            gameManager = _gameManager;
            type = _type;
        }
    
        //鼠标点击
        private void OnMouseEnter()
        {
            gameManager.EnterSweet(this);
        }
    
        //鼠标按下
        private void OnMouseDown()
        {
            gameManager.PressSweet(this);
        }
    
        //鼠标抬起
        private void OnMouseUp()
        {
            gameManager.ReleaseSweet();
        }
    }
    GameSweet.cs
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public class GameManager : MonoBehaviour {
    
        //甜品的种类
        public enum SweetsType
        {
            EMPTY,
            NORMAL,
            BARRIER,
            ROE_CLEAR,
            COLUMN_CLEAR,
            RAINBOWCANDY,
            COUNT   //标记类型
        }
    
        //甜品预制体的字典,我们可以通过甜品的种类来得到对应的甜品游戏物体
        public Dictionary<SweetsType, GameObject> sweetPrefabDict;
    
        [System.Serializable]
        public struct SweetPrefab
        {
            public SweetsType type;
            public GameObject prefab;
        }
    
        public SweetPrefab[] sweetPrefabs;
    
        //单例实例化
        private static GameManager _instance;
        public static GameManager Instance
        {
            get
            {
                return _instance;
            }
    
            set
            {
                _instance = value;
            }
        }
    
        //大网格的行列数
        public int xColumn;
        public int yRow;
    
        //填充时间
        public float fillTime;
    
        public GameObject gridPrefab;
    
        //甜品数组
        private GameSweet[,] sweets;
    
        //要交换的两个甜品对象
        private GameSweet pressedSweet;
        private GameSweet enteredSweet;
    
        private void Awake()
        {
            _instance = this;
        }
    
        // Use this for initialization
        void Start() {
    
            //字典的实例化
            sweetPrefabDict = new Dictionary<SweetsType, GameObject>();
    
            for(int i=0;i<sweetPrefabs.Length;i++)
            {
                if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
                {
                    sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
                }
            }
    
           for(int x = 0; x < xColumn; x++)
            {
                for (int y=0;y<yRow;y++)
                {
                    GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
                    chocolate.transform.SetParent(transform);
                }
            }
    
            sweets = new GameSweet[xColumn, yRow];
            for (int x = 0; x < xColumn; x++)
            {
                for (int y = 0; y < yRow; y++)
                {
                    CreateNewSweet(x, y, SweetsType.EMPTY);
                }
            }
    
            //在(4,4)这个坐标点生成障碍物
            Destroy(sweets[4, 4].gameObject);
            CreateNewSweet(4,4,SweetsType.BARRIER);
    
            StartCoroutine(AllFill());
        }
        
        // Update is called once per frame
        void Update () {
            
        }
    
        public Vector3 CorrectPosition(int x ,int y)
        {
            //实际需要实例化巧克力的X位置 = GameManager位置的X坐标-大网格长度的一半+行列对应的X坐标
            // 实际需要实例化巧克力的Y位置 = GameManager位置的Y坐标-大网格长度的一半+行列对应的Y坐标
            return new Vector3(transform.position.x-xColumn/2f+x,transform.position.y+yRow/2f-y);
        }
    
        //产生甜品的方法
        public GameSweet CreateNewSweet(int x,int y,SweetsType type)
        {
            GameObject newSweet =  Instantiate(sweetPrefabDict[type], CorrectPosition(x, y), Quaternion.identity);
            newSweet.transform.parent = transform;
    
            sweets[x, y] = newSweet.GetComponent<GameSweet>();
            sweets[x, y].Init(x,y,this,type);
    
            return sweets[x, y];
        }
    
        //填充甜品的方法
        public IEnumerator AllFill()
        {
            bool needRefill = true;
    
            while(needRefill)
            {
                //完成上次填充动画
                yield return new WaitForSeconds(fillTime);
                while (Fill())
                {
                    yield return new WaitForSeconds(fillTime);
                }
    
                //清除所有我们意见匹配好的甜品
                needRefill = ClearAllMatchedSweet();
            }
    
        }
    
        //分布填充
        public bool Fill()
        {
            bool FilledNotFinshed = false;  //用来判断本次是否完成
    
            //行遍历
            for(int y=yRow-2;y>=0;y--)
            {
                for(int x=0;x<xColumn;x++)
                {
                    GameSweet sweet = sweets[x, y]; //得到当前元素位置
    
                    //如果无法移动,则无法往下填充
                    if (sweet.CanMove())
                    {
                        GameSweet sweetBelow = sweets[x, y + 1]; 
    
                        if(sweetBelow.Type == SweetsType.EMPTY)//垂直填充
                        {
                            Destroy(sweetBelow.gameObject);
                            sweet.MovedComponet.Move(x,y+1,fillTime);
                            sweets[x, y + 1] = sweet;
                            CreateNewSweet(x, y, SweetsType.EMPTY);
                            FilledNotFinshed = true;
                        }
                        else
                        {
                            //-1代表左,1代表右
                            for (int down = -1; down <= 1; down++)
                            {
                                if (down != 0)
                                {
                                    int downX = x + down;
                                    //排除边界的时候
                                    //左下方
                                    if (downX >= 0 && downX < xColumn)
                                    {
                                        GameSweet downSweet = sweets[downX, y + 1];
                                        if (downSweet.Type == SweetsType.EMPTY)
                                        {
                                            bool canfill = true;    //用来判断垂直填充是否可以满足填充要求
                                            for (int aboutY = y; aboutY >= 0; aboutY--)
                                            {
                                                GameSweet sweetAbove = sweets[downX, aboutY];
                                                if (sweetAbove.CanMove())
                                                {
                                                    break;
                                                }
                                                else if (!sweetAbove.CanMove() && sweetAbove.Type != SweetsType.EMPTY)
                                                {
                                                    canfill = false;
                                                    break;
                                                }
                                            }
    
                                            if (!canfill)
                                            {
                                                Destroy(downSweet.gameObject);
                                                sweet.MovedComponet.Move(downX, y + 1, fillTime);
                                                sweets[downX, y + 1] = sweet;
                                                CreateNewSweet(x, y, SweetsType.EMPTY);
                                                FilledNotFinshed = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                   
                }
    
            }
            //最上排的特殊情况
            for (int x = 0; x < xColumn; x++)
               {
                   GameSweet sweet = sweets[x, 0];
    
                  if(sweet.Type == SweetsType.EMPTY)
                  {
                        GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-1), Quaternion.identity);
                        newSweet.transform.parent = transform;
    
                        sweets[x, 0] = newSweet.GetComponent<GameSweet>();
                        sweets[x, 0].Init(x, -1,this,SweetsType.NORMAL);
                        sweets[x, 0].MovedComponet.Move(x, 0,fillTime);
                        sweets[x, 0].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(0,sweets[x,0].ColorComponet.NumColors));
                    FilledNotFinshed = true;      
                  }
            }
            return FilledNotFinshed;
        }
    
        //甜品是否相邻的判断方法
        private bool IsFriend(GameSweet sweet1,GameSweet sweet2)
        {
            return (sweet1.X == sweet2.X && Mathf.Abs(sweet1.Y-sweet2.Y)==1)||(sweet1.Y==sweet2.Y&&Mathf.Abs(sweet1.X-sweet2.X)==1);
        }
    
        //交换两个甜品
        private void ExchangeSweets(GameSweet sweet1, GameSweet sweet2)
        {
            if (sweet1.CanMove() && sweet2.CanMove())
            {
                sweets[sweet1.X, sweet1.Y] = sweet2;
                sweets[sweet2.X, sweet2.Y] = sweet1;
    
                if (MatchSweets(sweet1, sweet2.X, sweet2.Y) != null || MatchSweets(sweet2, sweet1.X, sweet1.Y) != null)
                {
                    int tempX = sweet1.X;
                    int tempY = sweet1.Y;
    
    
                    sweet1.MovedComponet.Move(sweet2.X, sweet2.Y, fillTime);
                    sweet2.MovedComponet.Move(tempX, tempY, fillTime);
    
                    ClearAllMatchedSweet();
                    //消除甜品时两侧甜品进行填充
                    StartCoroutine(AllFill());
    
                }
                else 
                {
                    sweets[sweet1.X, sweet1.Y] = sweet1;
                    sweets[sweet2.X, sweet2.Y] = sweet2;
                }
    
            }
        }
    
        public void PressSweet(GameSweet sweet)
        {
            pressedSweet = sweet;
    
        }
    
        public void EnterSweet(GameSweet sweet)
        {
            enteredSweet = sweet;
        }
    
        public void ReleaseSweet()
        {
            if (IsFriend(pressedSweet, enteredSweet))
            {
                ExchangeSweets(pressedSweet, enteredSweet);
            }
        }
    
        //匹配方法
        public List<GameSweet> MatchSweets(GameSweet sweet, int newX, int newY)
        {
            if (sweet.CanColor())
            {
                ColorSweet.ColorType color = sweet.ColorComponet.Color;
                List<GameSweet> matchRowSweets = new List<GameSweet>();
                List<GameSweet> matchLineSweets = new List<GameSweet>();
                List<GameSweet> finishedMatchingSweets = new List<GameSweet>();
    
                //行匹配
                matchRowSweets.Add(sweet);
    
                //i=0代表往左,i=1代表往右
                for (int i = 0; i <= 1; i++)
                {
                    for (int xDistance = 1; xDistance < xColumn; xDistance++)
                    {
                        int x;
                        if (i == 0)
                        {
                            x = newX - xDistance;
                        }
                        else
                        {
                            x = newX + xDistance;
                        }
                        if (x < 0 || x >= xColumn)
                        {
                            break;
                        }
    
                        if (sweets[x, newY].CanColor() && sweets[x, newY].ColorComponet.Color == color)
                        {
                            matchRowSweets.Add(sweets[x, newY]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                if (matchRowSweets.Count >= 3)
                {
                    for (int i = 0; i < matchRowSweets.Count; i++)
                    {
                        finishedMatchingSweets.Add(matchRowSweets[i]);
                    }
                }
    
                //L T型匹配
                //检查一下当前行遍历列表中的元素数量是否大于3
                if (matchRowSweets.Count >= 3)
                {
                    for (int i = 0; i < matchRowSweets.Count; i++)
                    {
                        //行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
                        // 0代表上方 1代表下方
                        for (int j = 0; j <= 1; j++)
                        {
                            for (int yDistance = 1; yDistance < yRow; yDistance++)
                            {
                                int y;
                                if (j == 0)
                                {
                                    y = newY - yDistance;
                                }
                                else
                                {
                                    y = newY + yDistance;
                                }
                                if (y < 0 || y >= yRow)
                                {
                                    break;
                                }
    
                                if (sweets[matchRowSweets[i].X, y].CanColor() && sweets[matchRowSweets[i].X, y].ColorComponet.Color == color)
                                {
                                    matchLineSweets.Add(sweets[matchRowSweets[i].X, y]);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
    
                        if (matchLineSweets.Count < 2)
                        {
                            matchLineSweets.Clear();
                        }
                        else
                        {
                            for (int j = 0; j < matchLineSweets.Count; j++)
                            {
                                finishedMatchingSweets.Add(matchLineSweets[j]);
                            }
                            break;
                        }
                    }
                }
    
                if (finishedMatchingSweets.Count >= 3)
                {
                    return finishedMatchingSweets;
                }
    
                matchRowSweets.Clear();
                matchLineSweets.Clear();
    
                matchLineSweets.Add(sweet);
    
                //列匹配
    
                //i=0代表往左,i=1代表往右
                for (int i = 0; i <= 1; i++)
                {
                    for (int yDistance = 1; yDistance < yRow; yDistance++)
                    {
                        int y;
                        if (i == 0)
                        {
                            y = newY - yDistance;
                        }
                        else
                        {
                            y = newY + yDistance;
                        }
                        if (y < 0 || y >= yRow)
                        {
                            break;
                        }
    
                        if (sweets[newX, y].CanColor() && sweets[newX, y].ColorComponet.Color == color)
                        {
                            matchLineSweets.Add(sweets[newX, y]);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                if (matchLineSweets.Count >= 3)
                {
                    for (int i = 0; i < matchLineSweets.Count; i++)
                    {
                        finishedMatchingSweets.Add(matchLineSweets[i]);
                    }
                }
    
                //L T型匹配
                //检查一下当前行遍历列表中的元素数量是否大于3
                if (matchLineSweets.Count >= 3)
                {
                    for (int i = 0; i < matchLineSweets.Count; i++)
                    {
                        //行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
                        // 0代表上方 1代表下方
                        for (int j = 0; j <= 1; j++)
                        {
                            for (int xDistance = 1; xDistance < xColumn; xDistance++)
                            {
                                int x;
                                if (j == 0)
                                {
                                    x = newY - xDistance;
                                }
                                else
                                {
                                    x = newY + xDistance;
                                }
                                if (x < 0 || x >= xColumn)
                                {
                                    break;
                                }
    
                                if (sweets[x, matchLineSweets[i].Y].CanColor() && sweets[x, matchLineSweets[i].Y].ColorComponet.Color == color)
                                {
                                    matchRowSweets.Add(sweets[x, matchLineSweets[i].Y]);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
    
                        if (matchRowSweets.Count < 2)
                        {
                            matchRowSweets.Clear();
                        }
                        else
                        {
                            for (int j = 0; j < matchRowSweets.Count; j++)
                            {
                                finishedMatchingSweets.Add(matchRowSweets[j]);
                            }
                            break;
                        }
                    }
                }
    
                if (finishedMatchingSweets.Count >= 3)
                {
                    return finishedMatchingSweets;
                }
            }
    
            return null;
        }
    
    
        //清除方法
        public bool ClearSweet(int x,int y)
        {
            if (sweets[x, y].CanClear()&&!sweets[x,y].ClearedCompent.IsClearing)
            {
                sweets[x, y].ClearedCompent.Clear();
                CreateNewSweet(x,y,SweetsType.EMPTY);
    
                return true;
            }
            return false;
        }
    
        //清除全部完成匹配的甜品
        private bool ClearAllMatchedSweet()
        {
            bool needRefill = false;
    
            for(int y = 0; y < yRow; y++)
            {
                for (int x=0;x<xColumn;x++)
                {
                    if (sweets[x, y].CanClear())
                    {
                         List<GameSweet> matchList = MatchSweets(sweets[x,y],x,y);
    
                        if (matchList != null)
                        {
                            for (int i=0;i<matchList.Count;i++)
                            {
                                if (ClearSweet(matchList[i].X, matchList[i].Y))
                                {
                                    needRefill = true;
                                }
                            }
                        }
                    }
                }
            }
            return needRefill;
        }
    }
    GameManager.cs
    (如需转载学习,请标明出处)
  • 相关阅读:
    5星|施展《枢纽》(上):中国历史就是中原跟草原、西域、雪域、西南、海洋的互动史
    乔布斯在位时,库克实质上已经在做CEO的工作了:3星|《蒂姆·库克传》
    3星|张维迎《企业家精神与中国经济》:逻辑不够严谨,有陷入锤子模式的嫌疑
    4星|《喜鹊谋杀案》:侦探小说手稿也是罪案工具和破案线索【严重剧透】
    近年读了1008本书,挑出32本5星好书
    2019左其盛好书榜,没见过更好的榜单(截至6月30日)
    他们怎么能如此丧尽天良:3星|《天生恶魔?:纽伦堡审判与罗夏墨迹测验》
    原始部落与现代社会成员的熟人数量都不超过邓巴数:3星|邓巴《社群的进化》
    C#文件或文件夹压缩和解压
    HttpWebRequest Timeout
  • 原文地址:https://www.cnblogs.com/1138720556Gary/p/9574221.html
Copyright © 2020-2023  润新知