Unity3D初級案例-經典貪吃蛇二

引言:承接上一篇貪吃蛇案例!喜歡我的就關注我啊,不然沒有繼續寫的動力啦!!!
開發版本:unity 2017.1.1f1
適合人羣:初學Unity者
源文件鏈接請見文末!
開啓學習之旅吧!


07 邊界傳送

完善蛇頭的觸發檢測,使用switch判斷蛇頭碰撞的牆面
//判斷碰撞到物體的名字
                switch (collision.gameObject.name)
                {
                    case "Up":
                        //-transform.localPosition.y + 30 需要注意這裏添加一個偏差值,防止蛇頭剛移動到底部就碰到底部的碰撞器,下面同理
                        transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + 30, transform.localPosition.z);
                        break;
                    case "Down":
                        transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 30, transform.localPosition.z);
                        break;
                    case "Left":
                        transform.localPosition = new Vector3(-transform.localPosition.x + 210, transform.localPosition.y, transform.localPosition.z);
                        break;
                    case "Right":
                        transform.localPosition = new Vector3(-375, transform.localPosition.y, transform.localPosition.z);
                        break;
                }

08 設計UI

首先實現分數和長度的記錄
新建MainUIController.cs腳本,做成單例模式
添加UpdateUI()方法,用於外部調用更新UI顯示

 private static MainUIController instance;
    public static MainUIController Instance
    {
        get
        {
            return instance;
        }
    }
 private void Awake()
    {
        if (instance == null)
        {
            instance = this;
        }
    }
    public int score = 0;
    public int length = 0;
    public Text scoreText;
    public Text lengthText;

 public void UpdateUI(int s = 5, int l = 1)
    {
        score += s;
        length += l;
        scoreText.text = "得分:\n" + score;
        lengthText.text = "長度:\n" + length;
    }
然後在SnakeHead.cs的觸發檢測中調用
if (collision.gameObject.CompareTag("Food"))
        {
            Destroy(collision.gameObject);
            MainUIController.Instance.UpdateUI();
            AddBody();
            FoodCreator.Instance.CreateFood((Random.Range(0, 100) < 20) ? true : false);
        }
        else if (collision.gameObject.CompareTag("Reward"))
        {
            Destroy(collision.gameObject);
            MainUIController.Instance.UpdateUI(Random.Range(5, 15) * 10);
            AddBody();
        }

設計暫停按鈕,新建Pause按鈕
public bool isPause = false;

 public void Pause()
    {
        isPause = !isPause;
        if (isPause)
        {
            Time.timeScale = 0;
            //按鈕圖片的切換
            pauseBtn.GetComponent<Image>().sprite = pauseSprites[1];
        }
        else
        {
            Time.timeScale = 1;
            pauseBtn.GetComponent<Image>().sprite = pauseSprites[0];
        }
    }

然後將暫停按鈕監聽Pause方法
同理,返回鍵就重新加載場景 注意引用命名空間using UnityEngine.UI;
public void BackToHome()
    {
        SceneManager.LoadScene("StartScene");
    }

設立一個布爾值用來判斷是否有邊界
public bool hasBorder
後續操作待定。。。

09 蛇死亡處理

實現蛇死亡特效
在SnakeHead.cs中添加Die()方法
public GameObject dieEffect;

  void Die()
    {
        audioSource.clip = dieClip;
        audioSource.Play();
        //取消蛇移動的InvokeRepeating調用
        CancelInvoke();
        isDie = true;
        //實例化死亡效果
        Instantiate(dieEffect, transform.position - Vector3.forward, Quaternion.identity);
        //數據持久化PlayerPrefs以鍵值對的形式保存數據,可以保存int、string、float三種數據類型,類似字典
        //Set用於保存數據,Get用於得到數據
        PlayerPrefs.SetInt("lastLength", MainUIController.Instance.length);
        PlayerPrefs.SetInt("lastScore", MainUIController.Instance.score);
        //如果當前分數高於最高分數,就將最高數據進行更換
        //GetInt("bestScore", 0)如果當前有bestScore值的話,則返回該值,如果沒有,則返回0
        if (PlayerPrefs.GetInt("bestScore", 0) < MainUIController.Instance.score)
        {
            PlayerPrefs.SetInt("bestLength", MainUIController.Instance.length);
            PlayerPrefs.SetInt("bestScore", MainUIController.Instance.score);
        }
        //開啓協成,調用GameOver方法
        StartCoroutine(GameOver(1.5f));
    }

    IEnumerator GameOver(float t)
    {
        //停頓t秒執行下面語句
        yield return new WaitForSeconds(t);
        //重新加載到開始場景
        UnityEngine.SceneManagement.SceneManager.LoadScene("StartScene");
    }

完善蛇頭觸發檢測
private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.gameObject.CompareTag("Food"))
        {
            Destroy(collision.gameObject);
            MainUIController.Instance.UpdateUI();
            AddBody();
            FoodCreator.Instance.CreateFood((Random.Range(0, 100) < 20) ? true : false);
        }
        else if (collision.gameObject.CompareTag("Reward"))
        {
            Destroy(collision.gameObject);
            MainUIController.Instance.UpdateUI(Random.Range(5, 15) * 10);
            AddBody();
        }
        else if (collision.gameObject.CompareTag("Body"))
        {
            Die();
        }
        else
        {
            if (MainUIController.Instance.hasBorder)
            {
                Die();
            }
            else
            {
                switch (collision.gameObject.name)
                {
                    case "Up":
                        transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + 30, transform.localPosition.z);
                        break;
                    case "Down":
                        transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 30, transform.localPosition.z);
                        break;
                    case "Left":
                        transform.localPosition = new Vector3(-transform.localPosition.x + 210, transform.localPosition.y, transform.localPosition.z);
                        break;
                    case "Right":
                        transform.localPosition = new Vector3(-375, transform.localPosition.y, transform.localPosition.z);
                        break;
                }
            }
        }
    }


10 存儲用戶設置

我們使用數據持久化保存PlayerPrefs來保存用戶的設置,實現保存玩家上一次的設置,上一節我們就用該方法保存了遊戲的得分
需要將蛇頭和所有蛇身的精靈資源放在Resources文件夾中,動態加載資源
新建四個方法BlueSelected(),YellowSelected(),BorderSelected(),NoBorderSelected(),分別綁定開始界面的四個Toggle選項
使用PlayerPrefs來存儲用戶設置

public class StartUIController : MonoBehaviour
{
    public Text lastText;
    public Text bestText;
    public Toggle blue;
    public Toggle yellow;
    public Toggle border;
    public Toggle noBorder;

    private void Start()
    {
        lastText.text = "上次:長度"+PlayerPrefs.GetInt("lastLength",0)+",分數" + PlayerPrefs.GetInt("lastScore", 0);
        bestText.text = "最好:長度" + PlayerPrefs.GetInt("bestLength", 0) + ",分數" + PlayerPrefs.GetInt("bestScore", 0);
        //GetString如果sh已經有值,則判斷是否爲樣式一小蛇,如果用戶還沒有設置,則默認爲樣式一
        if (PlayerPrefs.GetString("sh", "sb01") == "sb01")
        {
            blue.isOn = true;
            BlueSelected(true);
        }
        else
        {
            yellow.isOn = true;
            YellowSelected(true);
        }
        //有無邊界的判斷如上
        if (PlayerPrefs.GetInt("border", 0) == 1)
        {
            border.isOn = true;
            BorderSelected(true);
        }
        else
        {
            noBorder.isOn = true;
            NoBorderSelected(true);
        }
    }

    //選擇了樣式一小蛇
    public void BlueSelected(bool isOn)
    {
        if (isOn)
        {
            PlayerPrefs.SetString("sh", "sh01");
            PlayerPrefs.SetString("sb01", "sb0101");
            PlayerPrefs.SetString("sb02", "sb0102");
            //如果選擇該樣式,修改圖片顏色,用於區別
            blue.GetComponentInChildren<Image>().color = new Color32(1, 159, 232, 90);
        }
        else
        {
            blue.GetComponentInChildren<Image>().color = new Color32(1, 159, 232, 50);
        }
    }

    //選擇了樣式二小蛇
    public void YellowSelected(bool isOn)
    {
        if (isOn)
        {
            PlayerPrefs.SetString("sh", "sh02");
            PlayerPrefs.SetString("sb01", "sb0201");
            PlayerPrefs.SetString("sb02", "sb0202");
            yellow.GetComponentInChildren<Image>().color = new Color32(1, 159, 232, 90);
        }
        else
        {
            yellow.GetComponentInChildren<Image>().color = new Color32(1, 159, 232, 50);
        }
    }

    //選擇有邊界模式
    public void BorderSelected(bool isOn)
    {
        if (isOn)
        {
            PlayerPrefs.SetInt("border", 1);
        }
    }

    //選擇無邊界模式
    public void NoBorderSelected(bool isOn)
    {
        if (isOn)
        {
            PlayerPrefs.SetInt("border", 0);
        }
    }

    //開始遊戲
    public void StartGame()
    {
        UnityEngine.SceneManagement.SceneManager.LoadScene("MainScene");
    }
}

用戶設置已經存儲,需要在遊戲開始後,SnakeHead.cs中動態讀取設置
  private void Awake()
    {
        gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh01"));
        bodySprites[0] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0101"));
        bodySprites[1] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0102"));
    }
在MainUIController.cs中讀取用戶是否設置邊界
  private void Start()
    {
        //判斷是否設置了邊界
        if (PlayerPrefs.GetInt("border", 0) == 0)
        {
            //hasBorder標誌位用於判斷蛇頭碰到邊界是否死亡
            hasBorder = false;
            //遍歷bgImage父物體下所有子物體
            foreach (Transform item in bgImage.gameObject.transform)
            {
                //在無邊界模式下,禁用掉邊界
                item.gameObject.GetComponent<Image>().enabled = false;
            }
        }
        else
        {
            hasBorder = true;
        }
    }
添加音效和背景音樂都是相同操作,在此不再贅述!
對了,爲了方便,我直接設置屏幕大小爲1280*720,只需要在awake方法中加Screen.SetResolution(1280, 720,false);
基本完成遊戲的開發,大家也可以發揮想象力,再添磚加瓦,完善功能!

喜歡小生的請關注我哦!!!

素材及工程文件:鏈接:https://pan.baidu.com/s/1oAqV5OI 密碼:ua6v

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章