類似的規則很多,左右轉的差異也不一定是2或3,乍看之下會容易被圓餅搞混,事實上是可以把它想像一條直線有8個格子,前進跟後退的步數不同而已。
製作使用的Unity版本為5.4.1 f1。
實作測試(WebGL build,網頁跑起來有時候會頓一下滿怪的) (滑鼠點擊左右按鈕旋轉轉盤,當轉盤全部點亮就遊戲結束)
1、區塊
先來製作一個圓餅區塊的圖片,因為等下打算做成8個開關,所以先畫一個圓形然後切成8等分,接著把圖片匯入到Unity裡面。
接著要來編輯圖片的Pivot Point,所以打開該圖片的Sprite Editor,把這張區塊圖的Pivot Point移動到尖端再往下一點的位置,因為我想要讓等下變成圓餅圖後每個區塊之間會有一點空隙。
調整完畢後記得Apply貯存一下。
2、圓餅
接著用剛剛做好的區塊圖拉到場景上並且複製出8個相同的物件,每個區塊的Z軸角度稍微調整一下,因為是8等分,所以每個區塊會差異45度角。
從這張圖片來看,1的圖Z軸是0度,然後2的圖片Z軸是-45度,3的圖片是-90度,依此類推把8張圖轉完後就可以得到一張圓餅啦,圓餅的中間就是剛剛Pivot point的位置,因為稍微外推了一點,所以這張圓餅的每個區塊之間很明顯就可以看到有空隙來區隔了。
3、板子
開始來製作板子Component,同樣這次也是讓所有的判斷都寫在這裡,UI點擊按鈕後呼叫裡面的旋轉方法,然後去旋轉設定好的圓餅物件到正確的角度。
public class Board : MonoBehaviour { public GameObject piePanel; //包含所有區塊的圓餅物件 public float speed = 1; //圓餅旋轉的速度 public SpriteRenderer[] pie; //圓餅區塊的每個sprite物件 private int[] values; //每個區塊的欄位數值 private int currentIndex = 0; //當前的指標位置 private bool isRotating = false; //使否正在旋轉 void Start() { StartNewGame(); } public void StartNewGame() { values = new int[8]; //這邊圓餅切成8等分,所以宣告8個 currentIndex = Random.Range(0, 8); //隨機設定當前紅色箭頭所指的指標位置 for (int i = 0; i < values.Length; ++i) { //亂數調整該位置的開關 values[i] = (currentIndex == i) ? 1 : 1 - (Random.Range(0, 2) * 2); //調整對應的圓餅圖片的明暗 pie[i].color = (values[i] == 1) ? new Color32(255, 255, 255, 255) : new Color32(86, 86, 86, 255); //這邊設定打開的時候區塊是白色,關閉的時候是灰黑色 } //依據目前的指標位置把圓餅圖的Z軸設定到正確的位置 float initAngleZ = currentIndex * 45; piePanel.transform.eulerAngles = new Vector3(0, 0, initAngleZ); } //圓餅向左邊旋轉,UI製作一個Button然後把Button的OnClick新增一個事件並且呼叫這個Method,需要輸入的參數就是步數 public void RotateLeft(int value) { if (isRotating) return; StartCoroutine(RotateCoroutine(value)); } //圓餅向右邊旋轉,UI製作一個Button然後把Button的OnClick新增一個事件並且呼叫這個Method,需要輸入的參數就是步數 public void RotateRight(int value) { if (isRotating) return; StartCoroutine(RotateCoroutine(-value)); } //製作一個簡單的Coroutine來旋轉圓餅 private IEnumerator RotateCoroutine(int value) { isRotating = true; float rotateZ = value * 45; //依據步數來計算總共要旋轉的角度,往右旋轉的話是負的 float currentZ = currentIndex * 45; //依據當前的Index計算現在的角度 float targetZ = currentZ + rotateZ; //現在的角度加上要旋轉的角度就是最終的角度 while(true) { //開始依據時間計算Z的變動,同時設定調整圓餅物件的角度 currentZ = Mathf.MoveTowards(currentZ, targetZ, 45 * speed * Time.deltaTime); piePanel.transform.eulerAngles = new Vector3(0, 0, currentZ); //當目前角度差不多接近的時候,設定一個容許的誤差值,這邊是0.1,也可以用成public就可以在inspector裡面調 if (Mathf.Abs(targetZ - currentZ) < 0.1f) break; yield return null; } piePanel.transform.eulerAngles = new Vector3(0, 0, targetZ); //旋轉完畢,就需要把當前的index指標調整到正確的位置,同時切換int[]裡面數值的正負(用來代表開關) currentIndex = ((currentIndex + value) + 8) % 8; values[currentIndex] = -values[currentIndex]; //調整對應該index的圓餅圖片的明暗 pie[currentIndex].color = (values[currentIndex] == 1) ? new Color32(255, 255, 255, 255) : new Color32(86, 86, 86, 255); //檢查遊戲是否結束(全部圓餅都打開了),因為圓餅打開的數值是1,關閉的數值是-1,所以全部加總起來等於8就結束了 int totalValue = 0; foreach (int val in values) totalValue += val; if(totalValue == values.Length) { Debug.Log("Game Over"); //這邊製作遊戲結束的呼叫 } isRotating = false; } }
4、設定
最後把Board Component放進場景中,把每個區塊的Sprite設定進去,這邊順序跟前一張圖的順序一樣,然後在12點鐘的方向加一個紅色箭頭來表示目前的指標位置。
到此為止就結束了,接下來就是製作UI的按鈕,然後讓按鈕點下去的時候呼叫Board裡面的RotateLeft或RotateRight就好了,不過製作UI就不在這邊說明了。
也算是滿常見的遊戲機制,我這邊的實作用了亂數開場,所以有時候可能只要轉個一兩步就結束了,有時候可能要轉個很多次才會結束,這個的話可以改寫成預先設定版面的狀態,就不會有這樣的問題了。
如果有任何錯誤歡迎提出。
No comments:
Post a Comment