欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注同名公众号:Java学习之道

[转]Unity游戏开发之贪吃蛇(上)

  |   0 评论   |   0 浏览

作者: 虚拟喵

来源: https://blog.csdn.net/qq_35361471/article/details/79007419

效果预览

主要实现功能:WASD键或上下左右键控制蛇移动方向,吃到冰淇淋加分,并且增长蛇身。游戏提供两种蛇的样式可选,而且有两种有无边界模式可选。记录当前得分和历史最高分。

新建2D工程,新建StartScene场景,Game场景设置为1280*720大小,导入资源

我们使用UGUI制作UI及人物,开始界面效果如下:

Canvas要设置为Screen Sapce Camera模式

需要注意的是,皮肤和模式分别只能二选一,Toggle Group的Allow Switch off不能勾选

新建主场景MainScene,效果如下:

因为需要开发一个边界模式,新建四个对象,放入场景四边,并添加碰撞体,勾选Is Trigger

注意四面墙分别命名为Up,Down,Left,Right,新建一个父对象统一管理

有两种主要方式可以实现蛇的移动。微信搜索公众号 [爱上游戏开发],回复 “资料”,免费领取 200G 学习资料!

第一种方式,从蛇尾的最后开始一节开始,依次向前一节蛇身的位置移动

第二种,蛇头每向前移动一个位置,就将蛇尾的最后一节移动到蛇头刚才的位置

我们选择第一种方式,因为我们的蛇有两种颜色相间的蛇身,如果第二种方式,会让蛇身的颜色混乱

新建一个Image,命名为SnackHead,Source Image修改为蛇头图片,长宽设置为45*45,添加Rigidbody2D和BoxCollider2D组件,勾选Is Trigger,为其添加一个空的父物体Snack,方便管理蛇头和以后添加的蛇身

在SnakeHead上挂载脚本SnakeHead.cs

首先实现蛇头的移动,转头,空格键加速操作

实现主要思想,InvokeRepeating方法持续间隔一定时间调用控制蛇头移动的Move方法,然后Update方法监听按键,判断蛇头移动的XY增量

并实现蛇头转向,利用InvokeRepeating的间隔调用时间来控制蛇头移动的速度

需要注意根据实际情况设计蛇头移动步长Step的大小,最好能让蛇头在有限范围内移动整数步

public float velocity = 0.35f;
InvokeRepeating("Move", 0, velocity);
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.Space))
{
 InvokeRepeating("Move", 0, velocity - 0.2f);
 if (Input.GetKeyUp(KeyCode.Space))
 {
  InvokeRepeating("Move", 0, velocity);
  gameObject.transform.localRotation = Quaternion.identity;
  gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 180));
  gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 90));
  gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, -90));
  headPos = gameObject.transform.localPosition;
  gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);
 }
}

开发食物,新建一个Image,命名为SnackBody,source image设置为任意的食物图片,长宽设置为35*35,添加Box Collider2D,勾选is trigger, 需要注意碰撞器大小设置稍微小一点,防止蛇头擦肩而过的时候,发生碰撞,标签设置为Food,最后设为预制体。

设置步长step为30px,计算后得到世界坐标中心点到四周的步数,但为了防止出现食物"卡"在边缘,如下图,将步数各减一步

在Canvas下设置一个子物体FoodRoot,挂载脚本FoodCreator.cs

将FoodCreator设置为单例模式,只需实例化一次,方便调用

我们规定游戏开始,就生成一个食物,蛇每吃掉一个食物就随机生成其他食物,并有一定几率生成特殊奖励

特殊奖励的预制体和食物制作差不多。

public class FoodCreator : MonoBehaviour{
 private static FoodCreator instance;
 public static FoodCreator Instance
 public int xMinLimit = 11;
 public int xMaxLimit = 20;
 public int yMinLimit = 11;
 public int yMaxLimit = 11;
 public GameObject foodPrefabs;
 public GameObject rewardPrefabs;
 public Sprite[] foodSprites;
 private Transform foodHolder;
 foodHolder = GameObject.FindGameObjectWithTag("FoodRoot").transform;
 public void CreateFood(bool isReward)
 int index = Random.Range(0, foodSprites.Length);
 GameObject food = Instantiate(foodPrefabs);
 food.GetComponent<Image>().sprite = foodSprites[index];
 food.transform.SetParent(foodHolder, false);
 int x = Random.Range(-xMinLimit, xMaxLimit + 1);
 y = Random.Range(-yMinLimit, yMaxLimit + 1);        
  .transform.localPosition = new Vector3(x * step, y * step, 0);
 GameObject reward = Instantiate(rewardPrefabs);            
 reward.transform.SetParent(foodHolder, false);            
 x = Random.Range(-xMinLimit, xMaxLimit);            
 y = Random.Range(-yMinLimit, yMaxLimit);            
 reward.transform.localPosition = new Vector3(x * step, y * step, 0);
}

蛇身SnakeBody的制作和前面类似,tag设置为Body,设为预制体

我们使用List来存储蛇身,需要注意引用命名空间using System.Collections.Generic;

在SnakeHead.cs中新增AddBody()方法,然后添加OnTriggerEnter2D()用于触发检测,当碰到食物或者奖励的时候,调用AddBody()方法,实现蛇吃食物增加蛇身的功能

int index = (bodyList.Count % 2 == 0) ? 0 : 1;
GameObject newBody = Instantiate(bodyPrefab, new Vector3(2000, 2000, 0), Quaternion.identity);        
newBody.GetComponent<Image>().sprite = bodySprites[index];        
newBody.transform.SetParent(snackRoot, false);
bodyList.Add(newBody.transform);
private void OnTriggerEnter2D(Collider2D collision)
if (collision.gameObject.CompareTag("Food"))
{
 Destroy(collision.gameObject);
 FoodCreator.Instance.CreateFood((Random.Range(0, 100) < 20) ? true : false);
else if (collision.gameObject.CompareTag("Reward"))
    {
     Destroy(collision.gameObject);
    }
}

实现方法如图所示

在SnakeHead类中添加Move方法,使用 List记录蛇尾的位置信息

public ListbodyList = new List();

headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);
for (int i = bodyList.Count - 2; i >= 0; i--)
{
 bodyList[i + 1].localPosition = bodyList[i].localPosition;
    bodyList[0].localPosition = headPos;
}

标题:[转]Unity游戏开发之贪吃蛇(上)
作者:shirlnGame
地址:https://mmzsblog.cn/articles/2021/05/19/1621430293799.html
-----------------------------
如未加特殊说明,此网站文章均为原创。
网站转载须在文章起始位置标注作者及原文连接,否则保留追究法律责任的权利。
公众号转载请联系网站首页的微信号申请白名单!

个人微信公众号 ↓↓↓                 

微信搜一搜爱上游戏开发