using UnityEngine; using System.Collections; using Holoville.HOTween; /// <summary> /// 游戏逻辑 /// </summary> public class Main:MonoBehaviour { /// <summary> /// 点击框预设 /// </summary> public GameObject _indicator; /// <summary> /// 二维方块数组 /// </summary> public GameObject[,] _arrayOfShapes; /// <summary> /// 当前点击框 /// </summary> private GameObject _currentIndicator; /// <summary> /// 第一个选择的物体 /// </summary> private GameObject _FirstObject; /// 第二个选择的物体 /// </summary> private GameObject _SecondObject; /// <summary> /// 方块预设列表 /// </summary> public GameObject[] _listOfGems; /// <summary> /// 空物体 /// </summary> public GameObject _emptyGameobject; /// <summary> /// 星星特效 /// </summary> public GameObject _particleEffect; /// <summary> /// 匹配时的特效 /// </summary> public GameObject _particleEffectWhenMatch; /// <summary> /// 能否在对角线上转换 /// </summary> public bool _canTransitDiagonally = false; /// <summary> /// 每次匹配时的增长分数 /// </summary> public int _scoreIncrement; /// <summary> /// 总分 /// </summary> ; /// <summary> /// 当前特效 /// </summary> private ArrayList _currentParticleEffets = new ArrayList(); /// <summary> /// 匹配时的声音 /// </summary> public AudioClip MatchSound; /// <summary> /// 网格x轴上的格子数量 /// </summary> public int _gridWidth; /// <summary> /// 网格y轴上的格子数量 /// </summary> public int _gridHeight; void Start() { //为2维方块数组分配内存 _arrayOfShapes = new GameObject[_gridWidth,_gridHeight]; //从左到右,从下到上创建格子 ;i <= _gridWidth - ;i++) { ;j <= _gridHeight - ;j++) { //var gameObject = GameObject.Instantiate(_listOfGems[Random.Range(0,_listOfGems.Length)] as GameObject,new Vector3(i,j,0),transform.rotation) as GameObject; GameObject gameObject = null; ) { gameObject = GameObject.Instantiate(_listOfGems[] ),transform.rotation) as GameObject; } ) { gameObject = GameObject.Instantiate(_listOfGems[] ),transform.rotation) as GameObject; } else { gameObject = GameObject.Instantiate(_listOfGems[] ),transform.rotation) as GameObject; } _arrayOfShapes[i,j] = gameObject; } } //Adding the star effect to the gems and call the DoShapeEffect continuously //InvokeRepeating("DoShapeEffect",1f,0.21F); } void Update() { //是否转换 bool shouldTransit = false; //当用户点击按钮且没有动画 if(Input.GetButtonDown("Fire1") && HOTween.GetTweenInfos() == null) { //销毁当前选择框 Destroy(_currentIndicator); //生成从屏幕中心点到鼠标点击位置的射线 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //发射射线 RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(Input.mousePosition),Vector2.zero); //如果射线碰到物体 if(hit.transform != null) { //第一个选择的物体为空 if(_FirstObject == null) { //将点击的物体设置为第一个选择物体 _FirstObject = hit.transform.gameObject; //如果第一个选择的物体不为空 } else { //将点击的物体设置为第二个选择物体 _SecondObject = hit.transform.gameObject; //可以转换 shouldTransit = true; } //根据点击位置创建选择框 _currentIndicator = GameObject.Instantiate(_indicator,),transform.rotation) as GameObject; //如果可以转换 if(shouldTransit) { //获取两个物体之间的距离 var distance = _FirstObject.transform.position - _SecondObject.transform.position; //如果x,y的距离 都小于等于1 && Mathf.Abs(distance.y) <= ) { //如果不能在斜线上交换 if(!_canTransitDiagonally) { // && distance.y != ) { //销毁选择框 Destroy(_currentIndicator); _FirstObject = null; _SecondObject = null; return; } } //播放交换动画 DoSwapMotion(_FirstObject.transform,_SecondObject.transform); //交换在数组中的位置 DoSwapTile(_FirstObject,_SecondObject,ref _arrayOfShapes); //如果不能转换 } else { _FirstObject = null; _SecondObject = null; } //销毁选择框 Destroy(_currentIndicator); } } } //如果没有播放动画 if(HOTween.GetTweenInfos() == null) { //查找匹配的格子 var Matches = FindMatch(_arrayOfShapes); //如果找到匹配的格子 ) { //更新分数 _scoreTotal += Matches.Count * _scoreIncrement; //遍历匹配物体 foreach(GameObject go in Matches) { //播放匹配声音 GetComponent<AudioSource>().PlayOneShot(MatchSound); //创建匹配特效 ),transform.rotation) as GameObject; //1秒后销毁特效 Destroy(destroyingParticle,1f); //用空物体替换匹配物体 _arrayOfShapes[(),transform.rotation) as GameObject; //0.1秒后删除匹配物体 Destroy(go,0.1f); } _FirstObject = null; _SecondObject = null; DoEmptyDown(ref _arrayOfShapes); } //如果没有找到格子,将格子的位置复位 else if(_FirstObject != null && _SecondObject != null) { //播放交换动画 DoSwapMotion(_FirstObject.transform,_SecondObject.transform); //交换格子位置 DoSwapTile(_FirstObject,_SecondObject,ref _arrayOfShapes); _FirstObject = null; _SecondObject = null; } } //更新分数 (GetComponent(typeof(TextMesh)) as TextMesh).text = _scoreTotal.ToString(); } /// <summary> /// 查找匹配 /// </summary> /// <param name="cells"></param> /// <returns></returns> private ArrayList FindMatch(GameObject[,] cells) { //存储匹配的方块数组 ArrayList stack = new ArrayList(); //将列上至少3个颜色相同的方块放进数组中 //从左到右 ;x <= cells.GetUpperBound();x++) { //从下到上 ;y <= cells.GetUpperBound();y++) { //当前网格 var thiscell = cells[x,y]; //如果是空物体,忽略 if(thiscell.name == "Empty(Clone)") { continue; } //匹配数量 ; //y2 网格列上的最大索引 ); //y1 网格列内y格子上方的格子索引 int y1; //遍历列中其余的格子 ;y1 <= y2;y1++) { //如果是空物体或者名字不匹配,跳出循环 if(cells[x,y1].name == "Empty(Clone)" || thiscell.name != cells[x,y1].name) { break; } //匹配数量加一 matchCount++; } //如果匹配数量大于等于2 ) { //限制y1的最小值 y1 = Mathf.Min(cells.GetUpperBound(),y1 - ); //从 y遍历到 y1, for(var y3 = y;y3 <= y1;y3++) { //将不重复的格子添加到数组中 if(!stack.Contains(cells[x,y3])) { stack.Add(cells[x,y3]); } } } } } //将行上至少3个颜色相同的方块放进数组中 //从下到上 ;y < cells.GetUpperBound() + ;y++) { //从左到右 ;x < cells.GetUpperBound() + ;x++) { //当前网格 var thiscell = cells[x,y]; //如果是空物体,忽略 if(thiscell.name == "Empty(Clone)") { continue; } //匹配数量 ; //x2 网格行上的最大索引 ); //x1 网格行内x格子右方的格子索引 int x1; //遍历行中其余的格子 ;x1 <= x2;x1++) { //如果是空物体或者名字不匹配,跳出循环 if(cells[x1,y].name == "Empty(Clone)" || thiscell.name != cells[x1,y].name) { break; } //匹配数量加一 matchCount++; } //如果匹配数量大于等于2 ) { //限制x1的最小值 x1 = Mathf.Min(cells.GetUpperBound(),x1 - ); //从x遍历到 x1, for(var x3 = x;x3 <= x1;x3++) { //将不重复的格子添加到数组中 if(!stack.Contains(cells[x3,y])) { stack.Add(cells[x3,y]); } } } } } return stack; } /// <summary> /// 交换动画 /// </summary> void DoSwapMotion(Transform a,Transform b) { Vector3 posA = a.localPosition; Vector3 posB = b.localPosition; TweenParms parms = new TweenParms().Prop("localPosition",posB).Ease(EaseType.EaseOutQuart); HOTween.To(a,0.25f,parms).WaitForCompletion(); parms = new TweenParms().Prop("localPosition",posA).Ease(EaseType.EaseOutQuart); HOTween.To(b,0.25f,parms).WaitForCompletion(); } /// <summary> /// 交换网格在数组中的位置 /// </summary> void DoSwapTile(GameObject a,GameObject b,ref GameObject[,] cells) { GameObject cell = cells[(int)a.transform.position.x,(int)a.transform.position.y]; cells[(int)a.transform.position.x,(int)a.transform.position.y] = cells[(int)b.transform.position.x,(int)b.transform.position.y]; cells[(int)b.transform.position.x,(int)b.transform.position.y] = cell; } /// <summary> /// 移动网格 /// </summary> private void DoEmptyDown(ref GameObject[,] cells) { //从左到右 ;x <= cells.GetUpperBound();x++) { //从下到上 ;y <= cells.GetUpperBound();y++) { //当前网格 var thisCell = cells[x,y]; //如果是空网格 if(thisCell.name == "Empty(Clone)") { //从下往上遍历y轴网格 );y2++) { //如果不是空网格,交换 if(cells[x,y2].name != "Empty(Clone)") { cells[x,y] = cells[x,y2]; cells[x,y2] = thisCell; break; } } } } } //从左到右 ;x <= cells.GetUpperBound();x++) { //从下到上 ;y <= cells.GetUpperBound();y++) { //如果是空网格 if(cells[x,y].name == "Empty(Clone)") { //删除空格子 Destroy(cells[x,y]); //随机创建新格子 cells[x,y] = GameObject.Instantiate(_listOfGems[Random.Range(,_listOfGems.Length)] ) + ,),transform.rotation) as GameObject; } } } //从左到右 ;x <= cells.GetUpperBound();x++) { //从下到上 ;y <= cells.GetUpperBound();y++) { //将格子移动到指定位置 TweenParms parms = )).Ease(EaseType.EaseOutQuart); HOTween.To(cells[x,y].transform,.4f,parms); } } } /// <summary> /// 创建闪烁特效 /// </summary> void DoShapeEffect() { foreach(GameObject row in _currentParticleEffets) { Destroy(row); } ;i <= ;i++) _currentParticleEffets.Add(GameObject.Instantiate(_particleEffect,,_arrayOfShapes.GetUpperBound() + ),Random.Range(,_arrayOfShapes.GetUpperBound() + ),-),,,Random.Range(,1000f),)) as GameObject); } }
Main
视频:https://pan.baidu.com/s/1qXYv2Mw
项目:https://pan.baidu.com/s/1i55JGVj