引言:小生今日分享的是经典贪吃蛇案例,特别感谢Siki学院的老师们。
这里附上原视频链接: http://www.sikiedu.com/my/course/89 可以搭配起来学习哦!
小生会根据自己理解,做一些代码上的修改!大家也可以有自己的主见!
开发版本:unity 2017.1.1f1
适合人群:初学Unity者
源文件链接请见文末!
开启学习之旅吧!
效果预览:
主要实现功能:WASD键或上下左右键控制蛇移动方向,吃到冰淇淋加分,并且增长蛇身。游戏提供两种蛇的样式可选,而且有两种有无边界模式可选。记录当前得分和历史最高分。

01 场景搭建

新建2D工程,新建StartScene场景,Game场景设置为1280*720大小,导入资源
我们使用UGUI制作UI及人物,开始界面效果如下:
Canvas要设置为Screen Sapce Camera模式
需要注意的是,皮肤和模式分别只能二选一,Toggle Group的Allow Switch off不能勾选
新建主场景MainScene,效果如下:
因为需要开发一个边界模式,新建四个对象,放入场景四边,并添加碰撞体,勾选Is Trigger
注意四面墙分别命名为Up,Down,Left,Right,新建一个父对象统一管理

02 实现思路

有两种主要方式可以实现蛇的移动
第一种方式,从蛇尾的最后开始一节开始,依次向前一节蛇身的位置移动
第二种,蛇头每向前移动一个位置,就将蛇尾的最后一节移动到蛇头刚才的位置
我们选择第一种方式,因为我们的蛇有两种颜色相间的蛇身,如果第二种方式,会让蛇身的颜色混乱

03 开发蛇头

新建一个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;//每一步蛇头移动距离public int step;//x轴蛇头移动增量private int x;//y轴蛇头移动增量private int y;private void Start(){//初始化,让蛇头可以向上移动x = 0;y = step;//InvokeRepeating等待0秒,然后每隔velocity时间调用Move方法InvokeRepeating("Move", 0, velocity);}private void Update(){//虚拟轴控制移动float h = Input.GetAxis("Horizontal");float v = Input.GetAxis("Vertical");//Input.GetKeyDown键按下瞬间if (Input.GetKeyDown(KeyCode.Space)){//CancelInvoke先取消之前的InvokeRepeating命令CancelInvoke();//将间隔调用“Move”方法的时间减小,则蛇移动变快InvokeRepeating("Move", 0, velocity - 0.2f);}//Input.GetKeyUp键抬起瞬间if (Input.GetKeyUp(KeyCode.Space)){CancelInvoke();InvokeRepeating("Move", 0, velocity);}//如果此时y = -step说明蛇正在向下移动,为了防止蛇目前在向下移动,突然向上移动,加y != -step判断,以下同理{//设置当头上下左右移动的时候,蛇头的方向和移动方向一致,以下同理//Quaternion代表四元数,identity表示初始旋转角度,可理解为new Vector(0,0,0)gameObject.transform.localRotation = Quaternion.identity;//设置蛇的移动方向,x = 0,y = step说明蛇头在Y轴向上移动,以下同理x = 0;y = step;}if (v < 0 && y != step){//Quaternion.Euler将欧拉角转化为四元数,需要注意欧拉角要与移动方向匹配gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 180));x = 0;y = -step;}if (h < 0 && x != step){gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 90));x = -step;y = 0;}if (h > 0 && x != -step){gameObject.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, -90));x = step;y = 0;}}void Move(){//获取当前蛇头移动的局部坐标headPos = gameObject.transform.localPosition;//将蛇头当前的移动位置加上x轴和y轴的移动增量,实现蛇头的移动gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);}

04 食物生成

开发食物,新建一个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{get{return instance;}}public int xMinLimit = 11;public int xMaxLimit = 20;public int yMinLimit = 11;public int yMaxLimit = 11;//要和蛇头移动步长一致public int step = 30;public GameObject foodPrefabs;//设置public GameObject rewardPrefabs;//保存食物的Spritespublic Sprite[] foodSprites;private Transform foodHolder;private void Awake(){if (instance == null){instance = this;}}private void Start(){foodHolder = GameObject.FindGameObjectWithTag("FoodRoot").transform;//游戏开始时,就生成一个食物CreateFood(false);}public void CreateFood(bool isReward){//随机取得一个食物的下标int index = Random.Range(0, foodSprites.Length);//实例化food预制体GameObject food = Instantiate(foodPrefabs);//将食物的image source改为选中下标的食物food.GetComponent<Image>().sprite = foodSprites[index];//将food设置为foodHolder的子物体,false会使得food保持局部坐标不变food.transform.SetParent(foodHolder, false);//随机取得食物生成位置int x = Random.Range(-xMinLimit, xMaxLimit + 1);int y = Random.Range(-yMinLimit, yMaxLimit + 1);food.transform.localPosition = new Vector3(x * step, y * step, 0);//判断是否生成奖励if (isReward){//同理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);}}
}

05 处理蛇身的生成

蛇身SnakeBody的制作和前面类似,tag设置为Body,设为预制体
我们使用List<Transform>来存储蛇身,需要注意引用命名空间using System.Collections.Generic;
在SnakeHead.cs中新增AddBody()方法,然后添加OnTriggerEnter2D()用于触发检测,当碰到食物或者奖励的时候,调用AddBody()方法,实现蛇吃食物增加蛇身的功能
  void AddBody(){//三元运算符,如果bodyList.Count被2模除则返回0,否则返回1,控制身体奇偶数轮换颜色int index = (bodyList.Count % 2 == 0) ? 0 : 1;//new Vector3(2000, 2000, 0)先将身体实例化在屏幕外GameObject newBody = Instantiate(bodyPrefab, new Vector3(2000, 2000, 0), Quaternion.identity);newBody.GetComponent<Image>().sprite = bodySprites[index];newBody.transform.SetParent(snackRoot, false);//将新生成的蛇身加入到bodyList中bodyList.Add(newBody.transform);}private void OnTriggerEnter2D(Collider2D collision){if (collision.gameObject.CompareTag("Food")){Destroy(collision.gameObject);AddBody();//(Random.Range(0, 100) < 20) ? true : false 三元运算符 随机值小于20则返回true,否则falseFoodCreator.Instance.CreateFood((Random.Range(0, 100) < 20) ? true : false);}else if (collision.gameObject.CompareTag("Reward")){Destroy(collision.gameObject);AddBody();}
}

06 实现蛇移动

实现方法如图所示
在SnakeHead类中添加Move方法,使用 List<Transform>记录蛇尾的位置信息
public List<Transform> bodyList = new List<Transform>();
 void Move(){//获取当前蛇头移动的局部坐标headPos = gameObject.transform.localPosition;//将蛇头当前的移动位置加上x轴和y轴的移动增量,实现蛇头的移动gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, 0);//刚开始bodyList为空,防止报空指针if (bodyList.Count > 0){for (int i = bodyList.Count - 2; i >= 0; i--){//将前一节蛇尾的位置赋予后一节bodyList[i + 1].localPosition = bodyList[i].localPosition;}//将原来蛇头的位置赋予给下标为0的蛇尾,也就是蛇头后一节的蛇尾bodyList[0].localPosition = headPos;}//方法二:将蛇尾最后一节移至蛇头的位置//if (bodyList.Count > 0)//{//bodyList.Last()获取list最后的元素//    bodyList.Last().localPosition = headPos;//Insert将元素插入到指定位置//    bodyList.Insert(0, bodyList.Last());//RemoveAt移除指定下标的元素//    bodyList.RemoveAt(bodyList.Count - 1);//}}

Unity3D初级案例-经典贪吃蛇一相关推荐

  1. Unity3D初级案例-经典贪吃蛇二

    引言:承接上一篇贪吃蛇案例!喜欢我的就关注我啊,不然没有继续写的动力啦!!! 开发版本:unity 2017.1.1f1 适合人群:初学Unity者 源文件链接请见文末! 开启学习之旅吧! 07 边界 ...

  2. Unity学习笔记(1)-经典贪吃蛇2d

    第一次写博客,想想还是挺激动的.学习Unity3d也有一段时间了,现在分享下用Unity实现<经典贪吃蛇>游戏的一些心得,希望对爱好游戏开发的朋友们有所帮助.(也希望大佬们指点) 相信大家 ...

  3. Web前端学习笔记——JavaScript之面向对象游戏案例:贪吃蛇

    面向对象游戏案例:贪吃蛇 案例相关源码以上传到 GitHub :https://github.com/lipengzhou/new-snake 案例介绍 游戏演示 在线演示地址:贪吃蛇 案例目标 游戏 ...

  4. C 语言实现经典贪吃蛇游戏

    原文链接:C语言 贪吃蛇游戏 文章目录 一.说明 二.效果 2.1 欢迎界面 2.2 游戏规则 2.3 得分排行 2.4 退出游戏 2.5 游戏界面 2.6 游戏结束 三.源码 3.1 cmd.h 3 ...

  5. Android程序——经典贪吃蛇大作战逆向分析

    逆向分析 1. 实现目标 2. 使用工具 3. 实现原理 4. 核心思路 5. 实现过程 1. 实现内购 2.屏蔽游戏下线提醒信息 1. 实现目标 (1)屏蔽经典经典贪吃蛇大作战游戏的过期提醒 (2) ...

  6. 使用Python实现经典贪吃蛇游戏

    先上效果图: 目录 一.简介 二.项目目的 三.turtle的详细介绍 3.1.简单介绍turtle.Screen() 3.2.简单介绍turtle.Turtle() 四.项目源码 五.总结 一.简介 ...

  7. JavaScript 面向对象游戏案例:贪吃蛇

    面向对象游戏案例:贪吃蛇 案例相关源码以上传到 GitHub :https://github.com/sunna1/snake 案例介绍 案例目标 游戏的目的是用来体会js高级语法的使用 不需要具备抽 ...

  8. Canvas制作经典贪吃蛇

    目录 效果展示 功能描述 然后是我个人开发这个小游戏时的大致步骤或者说思路 源代码 index.html js.js common.css 效果展示 功能描述 "上""下 ...

  9. 面向对象游戏案例:贪吃蛇

    功能实现 搭建页面 放一个容器盛放游戏场景 div#map,设置样式 #map {width: 800px;height: 600px;background-color: #ccc;position: ...

最新文章

  1. 【数据库】 兴唐第二十七节课只sql注入
  2. 设计模式 — 结构型模式 — 享元模式
  3. Javascript在页面加载时的执行顺序(转载)
  4. java中可以用浮点作为循环变量吗_Java千问:Java循环语句的几个冷门知识点你都知道吗?...
  5. 2020年度国家自然科学基金医学领域结果公布(9月27后可查)
  6. Android Studio 在res中新建文件夹不显示
  7. Ubuntu 常用工具、指令安装
  8. cli vue 外部js 引入 文件_javascript - vue cli构建的项目中,vue组件里怎么引入外部js文件里的方法...
  9. mysql全局变量的使用_mysql - 变量的使用
  10. 摄像头实时帧率_能够侦测的摄像头,怎么选?
  11. python中self和cls的区别
  12. 洛谷——P1219 [USACO1.5]八皇后 Checker Challenge
  13. ADF12C UI根据row重定位VO的当前行
  14. 数据结构与算法80道
  15. 微信小程序怎么用?小程序有什么用?之501~600
  16. 仙人掌真的会防辐射吗
  17. C语言磁盘文件由,C语言对磁盘文件进行快速排序简单实例
  18. 正则,grep命令详解
  19. Rails db rake命令
  20. 学习数学建模算法与应用【数据预处理】

热门文章

  1. 用聚合数据API快速写出小程序 1
  2. 一个好看的Dialog样式实现,仿IOS
  3. 设计模式之桥接模式(Bridge Pattern):我允许你的自我,减去的是羁绊,留下的牵挂
  4. 学堂在线python面向对象程序设计试题_面向对象程序设计-中国大学mooc-试题题目及答案...
  5. 详解多镜头全景摄像机
  6. selenium元素定位截图
  7. JS获取当前时间的方法
  8. 看了林志颖的个人履历 我第一次被他震住了
  9. 7-4 最大子列和问题 (20 分)
  10. 线性代数(13): 特征值与特征向量