不在蛇身上
Coddy Unity 3D 贪吃蛇游戏 课程的第 9 课,共 14 课。
MoveFood() 会随机选择任意一个格子,包括被蛇占据的格子。蛇身下的食物要等蛇移开后才能吃到,蛇越长,这种情况发生得越频繁。
一种解决方法是不断重新选择,直到选到空格。这在空棋盘上可行,但棋盘越满,需要尝试的次数就越多;如果没有空格了,就会一直尝试。更可靠的解决方法是先列出所有空格,再从中选一个:每个空格被选中的概率相同,而且只需选一次就够了。电影院也会用同样的方式为迟到的客人安排座位:
List<int> free = new List<int>();
for (int seat = 1; seat <= 40; seat++)
{
if (!taken.Contains(seat)) free.Add(seat);
}
int pick = free[Random.Range(0, free.Count)];Random.Range(0, free.Count) 会返回从 0 到最后一个索引之间的索引,因为最大值不包含在内。为了生成列表,棋盘会询问蛇是否占据某个格子:这是 Snake 中的一个方法,用来检查蛇头和每一节蛇身。
挑战
中等食物不会落在蛇身上。
- 在
Snake中,编写public bool Occupies(Vector3 cell):如果该位置是蛇头所在的格子或任意一节蛇尾所在的格子,就返回 true。 - 在
GameManager的MoveFood()中,让 x 和 z 从-snake.edge循环到snake.edge,把每个满足!snake.Occupies(cell)的格子添加到List<Vector3> free,然后将食物放在free[Random.Range(0, free.Count)]上。
按下 Play 并让蛇变长:食物总会落在空格子上。然后点击 Check。
亲手试试
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Snake snake;
public GameObject foodPrefab;
private Transform food;
private int score;
void Awake()
{
Instance = this;
}
void Start()
{
food = Instantiate(foodPrefab).transform;
MoveFood();
}
public bool IsFood(Vector3 cell)
{
return cell == food.position;
}
public void Eat()
{
score++;
MoveFood();
}
void MoveFood()
{
int x = Random.Range(-snake.edge, snake.edge + 1);
int z = Random.Range(-snake.edge, snake.edge + 1);
food.position = new Vector3(x, 0f, z);
}
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
Unity 3D 贪吃蛇游戏中的所有课
自己练习: Unity 在线编辑器