Unity3D 小案例 像素贪吃蛇 第二期 蛇的觅食
像素贪吃蛇
食物生成
在场景中创建一个 2D 正方形,调整颜色,添加 Tag 并修改为 Food。
然后拖拽到 Assets 文件夹中变成预制体。
创建食物管理器 FoodManager.cs
,添加单例,可以设置食物生成的坐标范围,提供生成一个食物的方法。
因为 Random.Range
的取值范围是 [min, max)
,为了取到 max 的值,需要给右边界加一。
csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FoodManager : MonoBehaviour
{
public static FoodManager instance;
public GameObject food;
public int borderLeft = -8;
public int borderRight = 8;
public int borderTop = 4;
public int borderBottom = -4;
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
}
}
void Start()
{
// 初始生成一个食物
GenerateFood();
}
/// <summary>
/// 生成食物
/// </summary>
public void GenerateFood()
{
GameObject obj = Instantiate(food, transform);
int x = Random.Range(borderLeft, borderRight + 1);
int y = Random.Range(borderBottom, borderTop + 1);
obj.transform.position = new Vector3(x, y, 0);
}
}
在场景中创建节点,挂上脚本,拖拽引用。
运行游戏,可以看到场景中生成了一个食物。
吃掉食物
给食物的预制体添加碰撞体,勾选 Is Trigger
。
同样,蛇头也要添加碰撞体,还要再添加一个刚体,Body Type
设置为 Kinematic
,不需要受到重力影响。
在 Snake.cs
中添加碰撞函数,判断碰撞物体的标签是 Food,就销毁食物,生成新的蛇身,并生成下一个食物。
csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Snake : MonoBehaviour
{
// ...
void OnTriggerEnter2D(Collider2D other)
{
if (other.CompareTag("Food"))
{
Destroy(other.gameObject);
GenerateBody();
FoodManager.instance.GenerateFood();
}
}
}
此时运行游戏,蛇头可以吃掉食物了。
但是有时候蛇头还未到达食物的位置,食物就被吃掉了,甚至蛇头只是经过食物的附近,食物也消失了。这是因为碰撞体的范围问题,默认的 Size 是 (1, 1)
,可以稍微调小一些,例如 (0.5, 0.5)
。
调整后的效果: