关于贪吃蛇的移动的一个想法
发表于2018-10-18
最近闲聊时说到贪吃蛇,贪吃蛇的身体是由多个格子拼接成的,在移动蛇的身体的时候,要把每一个格子移动到上一个格子的位置。
换一个角度,蛇在移动的时候,可以看作是,在最前面加一个body,最后面去掉一个body,中间的body不动。如果将所有的body放在一个list中,在每一次移动的时候,只需要在list最首位添加一个body,然后删除最末位的body,就完成了移动效果,这样不论蛇身多长,都不会增加代码的计算量。
再优化一下,在每次移动时,将最末位的body,直接移到最首位,省去了创建首位、销毁末位的操作,代码试验了一下,可以完美实现移到功能:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SnakeControl : MonoBehaviour { [SerializeField] Transform bodyPrefab; List<Transform> bodyList = new List<Transform>(); Vector3 direct = Vector3.forward; float bodyItemSide = 1; float moveSpaceTime = 0.5f; void Start () { for (int i = 0; i < 10; i++) { AddBody(); } StartCoroutine(MoveSnake()); } void Update () { if (Input.GetKeyDown(KeyCode.E)) AddBody(); else if (Input.GetKeyDown(KeyCode.W)) direct = Vector3.forward; else if (Input.GetKeyDown(KeyCode.S)) direct = Vector3.back; else if(Input.GetKeyDown(KeyCode.A)) direct = Vector3.right; else if(Input.GetKeyDown(KeyCode.D)) direct = Vector3.left; } void AddBody() { Transform newBody = Instantiate(bodyPrefab, transform); bodyList.Add(newBody); if (bodyList.Count > 0) newBody.position = bodyList[bodyList.Count - 1].position; } IEnumerator MoveSnake() { while(true) { yield return new WaitForSeconds(moveSpaceTime); Move(); } } Transform moveItem; void Move() { if (bodyList.Count == 0) return; moveItem = bodyList[bodyList.Count - 1]; moveItem.position = bodyList[0].position + direct * bodyItemSide; bodyList.Remove(moveItem); bodyList.Insert(0, moveItem); } }