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)==)||(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_游戏核心算法的更多相关文章
- Unity3D_(游戏)甜品消消乐03_游戏UI设计
甜品消消乐01_游戏基础界面 传送门 甜品消消乐02_游戏核心算法 传送门 甜品消消乐03_游戏UI设计 传送门 (源码在文章最下面~) 实现过程 游戏界面UI 分数与时间的UI显示 有关游戏U ...
- Unity3D_(游戏)甜品消消乐01_游戏基础界面
甜品消消乐游戏 (脚本源码在游戏UI设计最下方) 三消游戏,存在L型消除有一点小Bug,当甜品在饼干附近消除时会清除饼干 饼干作为游戏障碍物时不可移动的,多块饼干并排时会挡住甜品掉落 发现消除类游戏的 ...
- Unity 3D游戏-消消乐(三消类)教程和源码
Unity 消消乐教程和源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 Start Game -- ...
- 消消乐、candy crush类三消游戏程序逻辑分析
最近在开发一款类似消消乐的三消游戏,在碰到实现斜方向下落的时候卡住了很长时间.好几天没有思路,原本的思路是一次性预判多个宝石的一连串运动路径,运用缓动运动队列来实现宝石运动路径,例如 下落->滑 ...
- 热门游戏<开心消消乐>的“加壳”诡计!!
好久没搞游戏了,前几天看了又又一次看了看<开心消消乐>的1.29最新版..于是故事開始了: 1.反编译分析 首先使用Androidkiller进行反编译,得到两个Smali代码目录:mal ...
- 用 Python 写个消消乐小游戏
提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏. 很多人学习python,不 ...
- 用Python写个开心消消乐小游戏
本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受 ...
- 【BZOJ4820】[SDOI2017]硬币游戏(高斯消元)
[BZOJ4820][SDOI2017]硬币游戏(高斯消元) 题面 BZOJ 洛谷 题解 第一眼的感觉就是构\(AC\)自动机之后直接高斯消元算概率,这样子似乎就是\(BZOJ1444\)了.然而点数 ...
- 【BZOJ1444】[JSOI2009]有趣的游戏(高斯消元,AC自动机)
[BZOJ1444][JSOI2009]有趣的游戏(高斯消元,AC自动机) 题面 BZOJ 题解 先把\(AC\)自动机构建出来,最好构成\(Trie\)图.然后这样子显然是在一个有向图中有一堆概率的 ...
随机推荐
- Android SDK安装与环境配置
一.单独下载只有sdk的包,SDK不包括在Android Studio里,适用于不需要Android Studio的用户,其他可自行去官网下载. 1:Android SDK (https://www. ...
- pwd命令和修改PS1环境变量在bash行的显示
一.pwd:显示当前所在的位置 语法 pwd [选项] ... 描述 打印当前工作目录的完整文件名. -L,--logical 从环境使用PWD,即使它包含符号链 ...
- SSM和Spring Boot常用配置比较
一.Dao层相关 1.Mysql相关: 1.1配置DataSource连接池: (1)SSM配置: <!-- 加密后配置自己写的解析文件 --> <bean class=" ...
- SQLAlchemy技术手册
一.ORM 框架简介 对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的.面向对象的开发方法是当今企业级应用开发环境中的主流开发方法 ...
- 关于redis的几件小事(四)redis的过期策略以及内存淘汰机制
1.数据为什么会过期? 首先,要明白redis是用来做数据缓存的,不是用来做数据存储的(当然也可以当数据库用),所以数据时候过期的,过期的数据就不见了,过期主要有两种情况, ①在设置缓存数据时制定了过 ...
- python视频学习笔记5(高级变量的类型)
知识点回顾: Python 中数据类型可以分为 **数字型** 和 **非数字型*** 数字型 * 整型 (`int`) * 浮点型(`float`) * 布尔型(`bool`) * 真 `True` ...
- <<,>>(有符号位移)和>>>(无符号位移)的使用方法,及差别
<< —— 有符号左移 >> —— 有符号右移 <<< —— 无符号左移 >>> —— 无符号右移 无符号移位(>&g ...
- ab测试nginx Nginx性能优化
转自:https://www.cnblogs.com/nulige/p/9369700.html 1.性能优化概述 在做性能优化前, 我们需要对如下进行考虑 1.当前系统结构瓶颈 观察指标 压力测试 ...
- R 语言中的简单线性回归
... sessionInfo() # 查询版本及系统和库等信息 getwd() path <- "E:/RSpace/R_in_Action" setwd(path) rm ...
- JavaWEB开发05_Bootstrap
上次课内容:什么JQ : write less do more 写更少的代码,做更多的事情 javascript函数库 基本选择器: ID选择器: #ID名称 类选择器: .类名 元素选择 ...