using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class Manager : MonoBehaviour { public static Manager _isnstance; //單例模式的引用 public Transform poolManager; //生成數字的池子 private GameObject numPrefab; //數字的預制體 public Number[,] numbers = new Number[4, 4]; //保存方格中的數組 //正在移動中的Num public List isMovingNum = new List(); public bool hasMove = false; //是否有數字發生了移動 public GameObject UIFinsh; //游戲結束頁面 void Awake() { _isnstance = this; } void Start() { numPrefab = Resources.Load("Num"); // 開始游戲 ReStartBtn(); // 游戲結束面板按鈕監聽,重新開始 UIFinsh.GetComponentInChildren
4.2 Number數字處理類
using System.Collections; using System.Collections.Generic; using System.Numerics; using UnityEngine; using UnityEngine.UI; using Vector3 = UnityEngine.Vector3; public class Number : MonoBehaviour { //在二維數組中的位置X,Y public int posX; public int posY; private int offsetX = -620; //顯示偏移,Y,,, private int offsetY = -620; private int space = 420; // 間距 private bool isMoving = false; //動畫是否播放過的計數 public int value; //產生數字是幾 private bool toDestroy; //判斷數字是否銷毀 public bool OneMove = false; //標識數字是否合并過一次 // Use this for initialization void Start() { // 80%成2的概率,更改本身的Sprite名字,以更換圖片 value = Random.value > 0.2f ? 2 : 4; this.GetComponent().sprite = LoadSprite(); do { posX = Random.Range(0, 4); posY = Random.Range(0, 4); } while (Manager._isnstance.numbers[posX, posY] != null); transform.localPosition = GetLocalPos(); // 存放數字本身到數組中,表示此位置有數字不能生成新的數字 Manager._isnstance.numbers[posX, posY] = this; if (Manager._isnstance.isDead()) { // 游戲失敗 Manager._isnstance.ShowUIFinsh(false); } } // Update is called once per frame void Update() { //播放一次動畫 if (!isMoving) { if (transform.localPosition != GetLocalPos()) { isMoving = true; StartCoroutine(MoveAni()); } } } // 移動動畫 IEnumerator MoveAni() { Debug.Log("移動動畫..."); float t = 0; for (int i = 0; i < 10; i++) { transform.localPosition = Vector3.Lerp(transform.localPosition, GetLocalPos(), t); t += 0.1f; yield return new WaitForEndOfFrame(); } // 移動結束的回調 MoveOver(); } #region 游戲核心移動算法 /// /// 核心,移動方法(有空格,有物體是否一樣) /// public void Move(int directionX, int directionY) { //Debug.Log("測試"); //==========向右移動================== if (directionX == 1) { int index = 1; // 空格標志 while (Manager._isnstance.isEmpty(posX+index,posY)) { index++; } // 有空格的移動 if (index>1) { if (!Manager._isnstance.isMovingNum.Contains(this)) { // 保證不會重復添加物體(數字)到列表, Manager._isnstance.isMovingNum.Add(this); } //移動一次,就生成兩個數字的標志符 Manager._isnstance.hasMove = true; //向空格位置移動 Manager._isnstance.numbers[posX, posY] = null; posX = posX + index - 1; Manager._isnstance.numbers[posX, posY] = this; } //有相同數字的移動 if (posX < 3 && value == Manager._isnstance.numbers[posX+1,posY].value && !Manager._isnstance.numbers[posX+1,posY].OneMove) { // 只合并一次的標志 Manager._isnstance.numbers[posX + 1, posY].OneMove = true; // 移動的標志,(生成新的物體(數字)) Manager._isnstance.hasMove = true; // 動畫播放的限定(有數字在列表中就不會重復播放第二次動畫) // 不會重復添加物體(數字)到列表, if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } // 碰到一樣的數字,講位置設為空 并銷毀本身標識(true), // 再將其位置上的值變為2倍,(更換成新的數字) toDestroy = true; Manager._isnstance.numbers[posX, posY] = null; Manager._isnstance.numbers[posX + 1, posY].value *= 2; posX += 1; } }else //===========向左移動================== if (directionX == -1) { int index = 1; while (Manager._isnstance.isEmpty(posX - index, posY)) { index++; } //有空格的移動 if (index > 1) { Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } Manager._isnstance.numbers[posX, posY] = null; posX = posX - index + 1; Manager._isnstance.numbers[posX, posY] = this; } //碰到相同數字的移動 if (posX > 0 && value == Manager._isnstance.numbers[posX - 1, posY].value && !Manager._isnstance.numbers[posX - 1, posY].OneMove) { Manager._isnstance.numbers[posX - 1, posY].OneMove = true; Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } toDestroy = true; Manager._isnstance.numbers[posX, posY] = null; Manager._isnstance.numbers[posX - 1, posY].value *= 2; posX -= 1; } }else //===========向上移動================== if (directionY == 1) { int index = 1; //空格標志 while (Manager._isnstance.isEmpty(posX , posY + index)) { index++; } //有空格的移動 if (index > 1) { Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } Manager._isnstance.numbers[posX, posY] = null; posY = posY + index - 1; Manager._isnstance.numbers[posX, posY] = this; } //有相同位置的移動 if (posY < 3 && value == Manager._isnstance.numbers[posX , posY + 1].value && !Manager._isnstance.numbers[posX, posY + 1].OneMove) { Manager._isnstance.numbers[posX , posY + 1].OneMove = true; Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } toDestroy = true; Manager._isnstance.numbers[posX, posY] = null; Manager._isnstance.numbers[posX , posY + 1].value *= 2; posY += 1; } }else //===========向下移動================== if (directionY == -1) { int index = 1; //空格標志位 while (Manager._isnstance.isEmpty(posX, posY - index)) { index++; } //有空格的移動 if (index > 1) { Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } Manager._isnstance.numbers[posX, posY] = null; posY = posY - index + 1; Manager._isnstance.numbers[posX, posY] = this; } //有相同數字的移動 if (posY > 0 && value == Manager._isnstance.numbers[posX, posY - 1].value && !Manager._isnstance.numbers[posX, posY - 1].OneMove) { Manager._isnstance.numbers[posX, posY -1].OneMove = true; Manager._isnstance.hasMove = true; if (!Manager._isnstance.isMovingNum.Contains(this)) { Manager._isnstance.isMovingNum.Add(this); } toDestroy = true; Manager._isnstance.numbers[posX, posY] = null; Manager._isnstance.numbers[posX, posY - 1].value *= 2; posY -= 1; } } } #endregion /// /// 動畫結束,標志改為false /// public void MoveOver() { isMoving = false; //若碰到了相同的數字 銷毀自己,和改變另一個圖片(數字) if (toDestroy) { Destroy(this.gameObject); value = Manager._isnstance.numbers[posX, posY].value; Manager._isnstance.numbers[posX, posY].GetComponent().sprite = LoadSprite(); //游戲成功 if (value == 4096) { Manager._isnstance.ShowUIFinsh(true); } } Manager._isnstance.isMovingNum.Remove(this); } Vector3 GetLocalPos() { return new Vector3(offsetX + posX * space, offsetY + posY * space, 0); } /// /// 根據數字加載對應圖片 /// /// Sprite LoadSprite() { return Resources.Load(value.ToString()); } }