Unity--链表实现贪吃蛇

  • 贪吃蛇的原理就是使用链表来控制每一个蛇身节点的移动,每个节点的移动都是上一个节点之前移动过的位置.

看图:

最终效果图:


效果图.png

1 首先用一个Sphere做蛇头,上面挂载着SnakeMove,他控制着自己以及第一个节点的移动,第一个节点也就是我们这里的mTop,然后再建立一个Cube作为预制体,上面挂载BodyScript,他掌管着下一个节点(next)的移动,当按住空格键的时候,生成这个预制体,他就成了尾节点(mTail),之前的mTail被替代,mTail负责好了下一个,这样推理下去,之后生成的每一个他都会自动管理要怎样移动了~(具体的还是看代码和注释吧)

2 代码如下:

SnakeMove

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

public class SnakeMove : MonoBehaviour
{
    private float mSpeed = 1.0f;
    private Vector3 mDir;
    private float mTime = 0.4f;

    //第一个蛇身节点
    public GameObject mCube;
    //作为蛇身的第一个节点
    public BodyScript mTop;
    //作为蛇身的最后一个节点
    public BodyScript mTail;
    //储存上一个节点的位置
    private Vector3 mPos;

    public Color RandomColor()
    {
        //随机颜色的RGB值。即刻得到一个随机的颜色  
        float r = Random.Range(0f, 1f);
        float g = Random.Range(0f, 1f);
        float b = Random.Range(0f, 1f);
        Color color = new Color(r, g, b);
        return color;
    }

    void Start()
    {
        mDir = Vector3.forward;
    }

    void Update()
    {
        //保证一次性移动一个单位的距离
        if (mTime > 0)
        {
            mTime -= Time.deltaTime;
            if (mTime < 0)
            {
                Move();
                mTime = 0.4f;
            }
        }
        //上下左右只改变方向
        if (Input.GetKeyDown(KeyCode.W))
        {
            mDir = Vector3.forward;
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            mDir = Vector3.back;
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            mDir = Vector3.left;
        }
        if (Input.GetKeyDown(KeyCode.D))
        {
            mDir = Vector3.right;
        }

        if (Input.GetKeyDown(KeyCode.Space))
        {
            //实例化一个节点
            GameObject newBody = Instantiate(mCube, new Vector3(1000, 0, 0), Quaternion.identity) as GameObject;
            newBody.GetComponent<MeshRenderer>().material.color = RandomColor();
            //第一个节点生成
            if (mTop == null)
            {

                //第一个节点
                mTop = newBody.GetComponent<BodyScript>();
                //将指针指向蛇身的第一节(因为此时只有一个节点)
                mTail = mTop;
            }
            //非第一次生成的情况
            else
            {
                //尾节点(当前最后一个节点)的下一个节点指向新生成的节点
                mTail.next = newBody.GetComponent<BodyScript>();
                //尾节点指向新生成的节点
                mTail = mTail.next;
            }
        }
    }

    void Move()
    {
        //记录移动前的位置
        mPos = this.transform.position;
        //蛇头向前移动
        this.transform.position += mDir * mSpeed;
        //让第一个节点跟着蛇头移动
        if (mTop != null)
            mTop.Move(mPos);
    }

}

BodyScript

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

public class BodyScript : MonoBehaviour {

    //第二个节点(第一个节点的下一个)
    public BodyScript next;
    //用来接收物体的临时位置    
    private Vector3 myPos;
    
    public void Move(Vector3 pos)
    {
        myPos = this.transform.position;
        this.transform.position = pos;
        //如果当前cube还有子节点,不是蛇尾最后一节
        if (next != null)
        {
            //加上蛇头的第三个节点开始以后的蛇身移动到上一个节点的位置
            next.Move(myPos);
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容