甜品消消乐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)==)||(sweet1.Y==sweet2.Y&&Mathf.Abs(sweet1.X-sweet2.X)==); }

  交换两个甜品的方法

 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 = ; i <= ; i++)
{
for(int xDistance = ; xDistance < xColumn; xDistance++)
{
int x;
if (i == )
{
x = newX - xDistance;
}
else
{
x = newX + xDistance;
}
if (x < || 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 >= )
{
for(int i = ; i < matchRowSweets.Count; i++)
{
finishedMatchSweets.Add(matchRowSweets[i]);
}
} if (finishedMatchSweets.Count >= )
{
return finishedMatchSweets;
} //列匹配
matchLineSweets.Add(sweet); //i=0代表往左,i=1代表往右
for (int i = ; i <= ; i++)
{
for (int yDistance = ; yDistance < yRow; yDistance++)
{
int y;
if (i == )
{
y = newY - yDistance;
}
else
{
y = newY + yDistance;
}
if (y < || 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 >= )
{
for (int i = ; i < matchLineSweets.Count; i++)
{
finishedMatchSweets.Add(matchLineSweets[i]);
}
} if (finishedMatchSweets.Count >= )
{
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 = ; i <= ; i++)
{
for (int xDistance = ; xDistance < xColumn; xDistance++)
{
int x;
if (i == )
{
x = newX - xDistance;
}
else
{
x = newX + xDistance;
}
if (x < || x >= xColumn)
{
break;
} if (sweets[x, newY].CanColor() && sweets[x, newY].ColorComponet.Color == color)
{
matchRowSweets.Add(sweets[x, newY]);
}
else
{
break;
}
}
} if (matchRowSweets.Count >= )
{
for (int i = ; i < matchRowSweets.Count; i++)
{
finishedMatchingSweets.Add(matchRowSweets[i]);
}
} //L T型匹配
//检查一下当前行遍历列表中的元素数量是否大于3
if (matchRowSweets.Count >= )
{
for (int i = ; i < matchRowSweets.Count; i++)
{
//行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
// 0代表上方 1代表下方
for (int j = ; j <= ; j++)
{
for (int yDistance = ; yDistance < yRow; yDistance++)
{
int y;
if (j == )
{
y = newY - yDistance;
}
else
{
y = newY + yDistance;
}
if (y < || 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 < )
{
matchLineSweets.Clear();
}
else
{
for (int j = ; j < matchLineSweets.Count; j++)
{
finishedMatchingSweets.Add(matchLineSweets[j]);
}
break;
}
}
} if (finishedMatchingSweets.Count >= )
{
return finishedMatchingSweets;
} matchRowSweets.Clear();
matchLineSweets.Clear(); matchLineSweets.Add(sweet); //列匹配 //i=0代表往左,i=1代表往右
for (int i = ; i <= ; i++)
{
for (int yDistance = ; yDistance < yRow; yDistance++)
{
int y;
if (i == )
{
y = newY - yDistance;
}
else
{
y = newY + yDistance;
}
if (y < || y >= yRow)
{
break;
} if (sweets[newX, y].CanColor() && sweets[newX, y].ColorComponet.Color == color)
{
matchLineSweets.Add(sweets[newX, y]);
}
else
{
break;
}
}
} if (matchLineSweets.Count >= )
{
for (int i = ; i < matchLineSweets.Count; i++)
{
finishedMatchingSweets.Add(matchLineSweets[i]);
}
} //L T型匹配
//检查一下当前行遍历列表中的元素数量是否大于3
if (matchLineSweets.Count >= )
{
for (int i = ; i < matchLineSweets.Count; i++)
{
//行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
// 0代表上方 1代表下方
for (int j = ; j <= ; j++)
{
for (int xDistance = ; xDistance < xColumn; xDistance++)
{
int x;
if (j == )
{
x = newY - xDistance;
}
else
{
x = newY + xDistance;
}
if (x < || 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 < )
{
matchRowSweets.Clear();
}
else
{
for (int j = ; j < matchRowSweets.Count; j++)
{
finishedMatchingSweets.Add(matchRowSweets[j]);
}
break;
}
}
} if (finishedMatchingSweets.Count >= )
{
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 = ; y < yRow; y++)
{
for (int x=;x<xColumn;x++)
{
if (sweets[x, y].CanClear())
{
List<GameSweet> matchList = MatchSweets(sweets[x,y],x,y); if (matchList != null)
{
for (int i=;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=;t<time;t+=Time.deltaTime)
{
sweet.transform.position = Vector3.Lerp(startPos,endPos,t/time);
yield return ;
} 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 = ; 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=;i<sweetPrefabs.Length;i++)
{
if (!sweetPrefabDict.ContainsKey(sweetPrefabs[i].type))
{
sweetPrefabDict.Add(sweetPrefabs[i].type,sweetPrefabs[i].prefab);
}
} for(int x = ; x < xColumn; x++)
{
for (int y=;y<yRow;y++)
{
GameObject chocolate = Instantiate(gridPrefab,CorrectPosition(x,y),Quaternion.identity);
chocolate.transform.SetParent(transform);
}
} sweets = new GameSweet[xColumn, yRow];
for (int x = ; x < xColumn; x++)
{
for (int y = ; y < yRow; y++)
{
CreateNewSweet(x, y, SweetsType.EMPTY);
}
} //在(4,4)这个坐标点生成障碍物
Destroy(sweets[, ].gameObject);
CreateNewSweet(,,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-;y>=;y--)
{
for(int x=;x<xColumn;x++)
{
GameSweet sweet = sweets[x, y]; //得到当前元素位置 //如果无法移动,则无法往下填充
if (sweet.CanMove())
{
GameSweet sweetBelow = sweets[x, y + ]; if(sweetBelow.Type == SweetsType.EMPTY)//垂直填充
{
Destroy(sweetBelow.gameObject);
sweet.MovedComponet.Move(x,y+,fillTime);
sweets[x, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
}
else
{
//-1代表左,1代表右
for (int down = -; down <= ; down++)
{
if (down != )
{
int downX = x + down;
//排除边界的时候
//左下方
if (downX >= && downX < xColumn)
{
GameSweet downSweet = sweets[downX, y + ];
if (downSweet.Type == SweetsType.EMPTY)
{
bool canfill = true; //用来判断垂直填充是否可以满足填充要求
for (int aboutY = y; aboutY >= ; 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 + , fillTime);
sweets[downX, y + ] = sweet;
CreateNewSweet(x, y, SweetsType.EMPTY);
FilledNotFinshed = true;
break;
}
}
}
}
}
}
} } }
//最上排的特殊情况
for (int x = ; x < xColumn; x++)
{
GameSweet sweet = sweets[x, ]; if(sweet.Type == SweetsType.EMPTY)
{
GameObject newSweet = Instantiate(sweetPrefabDict[SweetsType.NORMAL], CorrectPosition(x,-), Quaternion.identity);
newSweet.transform.parent = transform; sweets[x, ] = newSweet.GetComponent<GameSweet>();
sweets[x, ].Init(x, -,this,SweetsType.NORMAL);
sweets[x, ].MovedComponet.Move(x, ,fillTime);
sweets[x, ].ColorComponet.SetColor((ColorSweet.ColorType)Random.Range(,sweets[x,].ColorComponet.NumColors));
FilledNotFinshed = true;
}
}
return FilledNotFinshed;
} //甜品是否相邻的判断方法
private bool IsFriend(GameSweet sweet1,GameSweet sweet2)
{
return (sweet1.X == sweet2.X && Mathf.Abs(sweet1.Y-sweet2.Y)==)||(sweet1.Y==sweet2.Y&&Mathf.Abs(sweet1.X-sweet2.X)==);
} //交换两个甜品
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 = ; i <= ; i++)
{
for (int xDistance = ; xDistance < xColumn; xDistance++)
{
int x;
if (i == )
{
x = newX - xDistance;
}
else
{
x = newX + xDistance;
}
if (x < || x >= xColumn)
{
break;
} if (sweets[x, newY].CanColor() && sweets[x, newY].ColorComponet.Color == color)
{
matchRowSweets.Add(sweets[x, newY]);
}
else
{
break;
}
}
} if (matchRowSweets.Count >= )
{
for (int i = ; i < matchRowSweets.Count; i++)
{
finishedMatchingSweets.Add(matchRowSweets[i]);
}
} //L T型匹配
//检查一下当前行遍历列表中的元素数量是否大于3
if (matchRowSweets.Count >= )
{
for (int i = ; i < matchRowSweets.Count; i++)
{
//行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
// 0代表上方 1代表下方
for (int j = ; j <= ; j++)
{
for (int yDistance = ; yDistance < yRow; yDistance++)
{
int y;
if (j == )
{
y = newY - yDistance;
}
else
{
y = newY + yDistance;
}
if (y < || 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 < )
{
matchLineSweets.Clear();
}
else
{
for (int j = ; j < matchLineSweets.Count; j++)
{
finishedMatchingSweets.Add(matchLineSweets[j]);
}
break;
}
}
} if (finishedMatchingSweets.Count >= )
{
return finishedMatchingSweets;
} matchRowSweets.Clear();
matchLineSweets.Clear(); matchLineSweets.Add(sweet); //列匹配 //i=0代表往左,i=1代表往右
for (int i = ; i <= ; i++)
{
for (int yDistance = ; yDistance < yRow; yDistance++)
{
int y;
if (i == )
{
y = newY - yDistance;
}
else
{
y = newY + yDistance;
}
if (y < || y >= yRow)
{
break;
} if (sweets[newX, y].CanColor() && sweets[newX, y].ColorComponet.Color == color)
{
matchLineSweets.Add(sweets[newX, y]);
}
else
{
break;
}
}
} if (matchLineSweets.Count >= )
{
for (int i = ; i < matchLineSweets.Count; i++)
{
finishedMatchingSweets.Add(matchLineSweets[i]);
}
} //L T型匹配
//检查一下当前行遍历列表中的元素数量是否大于3
if (matchLineSweets.Count >= )
{
for (int i = ; i < matchLineSweets.Count; i++)
{
//行匹配列表中满足匹配条件的每个元素上下依次进行列遍历
// 0代表上方 1代表下方
for (int j = ; j <= ; j++)
{
for (int xDistance = ; xDistance < xColumn; xDistance++)
{
int x;
if (j == )
{
x = newY - xDistance;
}
else
{
x = newY + xDistance;
}
if (x < || 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 < )
{
matchRowSweets.Clear();
}
else
{
for (int j = ; j < matchRowSweets.Count; j++)
{
finishedMatchingSweets.Add(matchRowSweets[j]);
}
break;
}
}
} if (finishedMatchingSweets.Count >= )
{
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 = ; y < yRow; y++)
{
for (int x=;x<xColumn;x++)
{
if (sweets[x, y].CanClear())
{
List<GameSweet> matchList = MatchSweets(sweets[x,y],x,y); if (matchList != null)
{
for (int i=;i<matchList.Count;i++)
{
if (ClearSweet(matchList[i].X, matchList[i].Y))
{
needRefill = true;
}
}
}
}
}
}
return needRefill;
}
}

GameManager.cs

Unity3D_(游戏)甜品消消乐02_游戏核心算法的更多相关文章

  1. Unity3D_(游戏)甜品消消乐03_游戏UI设计

    甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计    传送门 (源码在文章最下面~) 实现过程 游戏界面UI 分数与时间的UI显示 有关游戏U ...

  2. Unity3D_(游戏)甜品消消乐01_游戏基础界面

    甜品消消乐游戏 (脚本源码在游戏UI设计最下方) 三消游戏,存在L型消除有一点小Bug,当甜品在饼干附近消除时会清除饼干 饼干作为游戏障碍物时不可移动的,多块饼干并排时会挡住甜品掉落 发现消除类游戏的 ...

  3. Unity 3D游戏-消消乐(三消类)教程和源码

    Unity 消消乐教程和源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Start Game -- ...

  4. 消消乐、candy crush类三消游戏程序逻辑分析

    最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...

  5. 热门游戏&lt;开心消消乐&gt;的“加壳”诡计!!

    好久没搞游戏了,前几天看了又又一次看了看<开心消消乐>的1.29最新版..于是故事開始了: 1.反编译分析 首先使用Androidkiller进行反编译,得到两个Smali代码目录:mal ...

  6. 用 Python 写个消消乐小游戏

    提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏. 很多人学习python,不 ...

  7. 用Python写个开心消消乐小游戏

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受 ...

  8. 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)

    [BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...

  9. 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)

    [BZOJ1444][JSOI2009]有趣的游戏(高斯消元,AC自动机) 题面 BZOJ 题解 先把\(AC\)自动机构建出来,最好构成\(Trie\)图.然后这样子显然是在一个有向图中有一堆概率的 ...

随机推荐

  1. Android SDK安装与环境配置

    一.单独下载只有sdk的包,SDK不包括在Android Studio里,适用于不需要Android Studio的用户,其他可自行去官网下载. 1:Android SDK (https://www. ...

  2. pwd命令和修改PS1环境变量在bash行的显示

    一.pwd:显示当前所在的位置 语法 pwd [选项] ... 描述       打印当前工作目录的完整文件名. -L,--logical              从环境使用PWD,即使它包含符号链 ...

  3. SSM和Spring Boot常用配置比较

    一.Dao层相关 1.Mysql相关: 1.1配置DataSource连接池: (1)SSM配置: <!-- 加密后配置自己写的解析文件 --> <bean class=" ...

  4. SQLAlchemy技术手册

    一.ORM 框架简介 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法 ...

  5. 关于redis的几件小事(四)redis的过期策略以及内存淘汰机制

    1.数据为什么会过期? 首先,要明白redis是用来做数据缓存的,不是用来做数据存储的(当然也可以当数据库用),所以数据时候过期的,过期的数据就不见了,过期主要有两种情况, ①在设置缓存数据时制定了过 ...

  6. python视频学习笔记5(高级变量的类型)

    知识点回顾: Python 中数据类型可以分为 **数字型** 和 **非数字型*** 数字型 * 整型 (`int`) * 浮点型(`float`) * 布尔型(`bool`) * 真 `True` ...

  7. <<,>>(有符号位移)和>>>(无符号位移)的使用方法,及差别

    <<  ——  有符号左移 >>  ——  有符号右移 <<<  ——  无符号左移 >>>  ——  无符号右移 无符号移位(>&g ...

  8. ab测试nginx Nginx性能优化

    转自:https://www.cnblogs.com/nulige/p/9369700.html 1.性能优化概述 在做性能优化前, 我们需要对如下进行考虑 1.当前系统结构瓶颈 观察指标 压力测试 ...

  9. R 语言中的简单线性回归

    ... sessionInfo() # 查询版本及系统和库等信息 getwd() path <- "E:/RSpace/R_in_Action" setwd(path) rm ...

  10. JavaWEB开发05_Bootstrap

    上次课内容:什么JQ : write less do more 写更少的代码,做更多的事情 javascript函数库 基本选择器: ​ ID选择器: #ID名称 ​ 类选择器: .类名 ​ 元素选择 ...