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);
    }
  
}
 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值