unity 實現貪喫蛇, C# , 組合模式+工廠模式

                                                        W鍵加速, A鍵左轉,D建右轉

新建一個Cube物體, 將其命名改爲SnakeHead  給他添加tag  標籤Player,  這裏的碰撞檢測用的Trigger, 給物體一個剛體

把重力去掉, Collider 中的 Is Trigger 勾上,  添加SnakeManage 腳本

2,新建一個Cube物體, 將其命名改爲SnakeBody  給他添加tag  標籤Player

3, 將SnakeHead , SnakeBody放到 SnakeManage腳本中

3, 在新建一個Cube,將其命名改爲CubeObj, 做成預製體, 放到Resources文件下

4, 建幾個 材質球,給他們 掛上

   

下面 就是 腳本實現

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class SnakeManage : MonoBehaviour
{
    public static SnakeManage Instance;
    protected List<SnakeBody> snakeList;

    public GameObject HeadObj;
    public GameObject BodyObjone;

    CubeFactory cubeFactory;
    private void Awake()
    {
        Instance = this;
        snakeList = new List<SnakeBody>();
        SnakeBody snakeHead = new SnakeHead(null, HeadObj);
        snakeList.Add(snakeHead);

        SnakeBody snakeBody = new SnakeBody(snakeHead, BodyObjone);
        snakeList.Add(snakeBody);

        //實例化一個生產Cubu的工廠類
        cubeFactory = new CubeFactory(5, 5f);
    }
    private void OnTriggerEnter(Collider other)
    {
        if (other.tag == "wall")
        {          
            isStart = false;          
        }
        else if (other.tag == "Player")
        {
            isStart = false;         
        }
        else
        {
            AddSnakeBody(other.gameObject);         
        }
    }
    void AddSnakeBody(GameObject targetObj)
    {
        // 手動刷新一下最後一個的oldPos
        snakeList[snakeList.Count - 1].RefreshPostion();
        SnakeBody snakeBodytwo = new SnakeBody(snakeList[snakeList.Count - 1], targetObj);
        snakeList.Add(snakeBodytwo);

        //減少Cube的計數
        cubeFactory.ReduceHaveCubeCount();
        targetObj.GetComponent<MeshRenderer>().material.color = Color.red;
        targetObj.tag = "Player";
        targetObj.name = "SnakeBody";
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }
    float timer;
    float speedtimer = 0.2f;
    bool isStart = false;
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
            ((SnakeHead)snakeList[0]).RotionLeft();
        if (Input.GetKeyDown(KeyCode.D))
            ((SnakeHead)snakeList[0]).RotionRight();
        if (Input.GetKey(KeyCode.W))
        {
            speedtimer = 0f;
      
        }
        if (Input.GetKeyUp(KeyCode.W))
        {
            speedtimer = 0.1f;
      
        }
        if (Input.GetKeyDown(KeyCode.Space))
            isStart = !isStart;
        //物體的移動
        if (isStart)
        {
            timer += Time.deltaTime;
            if (timer > speedtimer)
            {
                timer = 0f;
                snakeList[0].MoveFont();
                for (int i = 1; i < snakeList.Count; i++)
                {
                    snakeList[i].FollowBody();
                }
            }
            
        }
        //產生Cube
        cubeFactory.UpdataBuildCube();
       
    }
}
下面是SnakeBody類

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SnakeBody
{
    //記錄上一個的物體的SnakeBody
    SnakeBody snakeBody;
    public  GameObject owerObj;
    //記錄移動前的位置
    Vector3 oldPos; 
    public SnakeBody(SnakeBody snakeBody, GameObject obj)
    {
        this.snakeBody = snakeBody;
        this.owerObj = obj;
        oldPos = this.owerObj.transform.position;
    }

    public void RefreshPostion()
    {
        oldPos = owerObj.transform.position;
    }
    public void FollowBody()
    {
        owerObj.transform.position = snakeBody.oldPos;
        snakeBody.RefreshPostion();
    }
    public virtual void MoveFont()
    {      
    }
}
public class SnakeHead:SnakeBody
{
    public SnakeHead(SnakeHead snakeHead, GameObject obj) : base(snakeHead, obj)
    {
    }
    public override void MoveFont()
    {
        //一次 走1米, Cube的大小 爲1米
        owerObj.transform.Translate(Vector3.forward);
    }
    public void RotionLeft()
    {
        Vector3 angle = owerObj.transform.localEulerAngles;
        angle.y -= 90f;
        owerObj.transform.localEulerAngles = angle;
    }

    public void RotionRight()
    {
        Vector3 angle = owerObj.transform.localEulerAngles;
        angle.y += 90f;
        owerObj.transform.localEulerAngles = angle;
    }

}
下面 是產生新的 Cube 工廠類

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class CubeFactory 
{
    Object cubeObj;
    int buildCubeCount;
    protected int BuildCubeCount
    {
        get { return buildCubeCount; }
        set { buildCubeCount = value; }
    }
    private int haveCubeMaxCount;
    protected int HaveCubeMaxCount
    {
        get { return haveCubeMaxCount; }
        set { haveCubeMaxCount = value; }
    }

    private float buildIntervalTime;
    protected float BuildIntervalTime
    {
        get { return buildIntervalTime; }
        set { buildIntervalTime = value; }
    }

    private float timer = 0f;
    public CubeFactory(int buildMaxCubeCount,float buildIntervalTime)
    {
        cubeObj = Resources.Load("CubeObj");
       // SnakeManage.Instance.ReduceCount = ReduceHaveCubeCount;
        this.HaveCubeMaxCount = buildMaxCubeCount;
        this.BuildIntervalTime = buildIntervalTime;
        timer = 0;
        BuildCubeCount = 0;
        InitCube();
    }
    public void ReduceHaveCubeCount()
    {
        BuildCubeCount--;
    }
    public void UpdataBuildCube()
    {
        timer += Time.deltaTime;
        if (timer > BuildIntervalTime&& BuildCubeCount<HaveCubeMaxCount)
        {
            Debug.Log(BuildCubeCount + " " + HaveCubeMaxCount);
           
            timer = 0f;
            InitCube();
        }
    }
    void InitCube()
    {
        BuildCubeCount++;
        GameObject obj = GameObject.Instantiate(cubeObj) as GameObject;
        float posx = Random.Range(-18, 18);
        float posy = Random.Range(-18, 18);
        obj.transform.position = new Vector3(posx, 0, posy);
    }
  
}
 

 

 

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