- 📢博客主页:https://blog.csdn.net/zhangay1998
- 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
- 📢本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉
- 📢未来很长,值得我们全力奔赴更美好的生活✨
目录
- 📣前言
- 🎬贪吃蛇小游戏制作
- 🎥游戏介绍
- 🏳️🌈打开Unity 新建一个项目,导入素材资源包
- 🏳️🌈新建一个场景,设置 开始场景 的界面
- 🏳️🌈设置 开始场景 的 侧边栏
- 🏳️🌈新建一个场景,设置 游戏场景 的界面
- 🏳️🌈给游戏场景添加可视化边界
- 🏳️🌈制作小蛇并让其移动
- 🏳️🌈随机生成食物、食物被吃掉 和 生成新的食物
- 🏳️🌈小蛇吃食物变长 和 蛇身的移动
- 🏳️🌈蛇身边界传送效果
- 🏳️🌈分数和长度的记录
- 🏳️🌈游戏暂停 和 菜单键 的设置
- 🏳️🌈蛇死亡的处理 和 游戏得分记录
- 🏳️🌈用户的设置和储存
- 🏳️🌈游戏打包及发布
- 🎄源码展示
- 🎁游戏源码下载 和 效果展示
- 👥总结
- 🚀往期优质文章分享
📣前言
- 今天给大家带来一款经典的贪吃蛇小游戏,相信大家应该都应该玩过
- 包括小时候在经典的诺基亚手机上,也是百玩不厌,算是最经典的游戏之一了!
- 那今天就来学习一下怎样制作这个经典的贪吃蛇小游戏吧!
🎬贪吃蛇小游戏制作
🎥游戏介绍
-
本篇小游戏使用Unity引擎制作一款经典的贪吃蛇小游戏
-
跟小时候玩过诺基亚手机上的玩法类似,然后使用一套自己的素材制作
-
有两种游戏模式 和 两款小蛇的皮肤,每当吃到食物就会变长!
-
本篇教程使用的Unity的版本是2018.4.24,不同版本可能会出现略微差异
-
文章字数挺多,其实整个游戏只用了四个脚本,直接结合源码看文章效果更佳!
🏳️🌈打开Unity 新建一个项目,导入素材资源包
第一步还是老样子,先打开UnityHub
,新建一个项目
这里要注意的是选择一个2D项目
,因为贪吃蛇是一个2D游戏
所以我们只需要创建一个 2D项目 而不需要 3D项目!如下所示
创建完了之后我们需要导入一个贪吃蛇的素材包,这个素材包
在文章后面我会和源码
一起分享!
先来看看导入之后这个资源包中都有什么内容吧!
导入之后工程目录结构如下:
有一个声音文件夹
、模型文件夹
、文字文件夹
和精灵图片文件夹
里面都包含几个简单的贪吃蛇
会用到的对应文件
🏳️🌈新建一个场景,设置 开始场景 的界面
在工程下新建一个场景Sence
然后新建一个Image
,然后将画布的渲染模式改为摄像机渲染
将Image
设置跟画布一个大小
把资源包中的这个背景拖到Image
上,这样的话Image
就会作为一个游戏背景来显示~
- 然后把
image
改名为bg
,然后再新建一个Image
,改名为ControllerPanel
- 这个新建的
Image
作为一个开始场景中的侧边栏,调整一下位置,放到Canvas左侧! - 然后还要新建一个
Text
文本组件,调整一下Text
的位置,放到Canvas上边侧就好 - 然后输入
贪吃蛇
,改个字体大小,字体选择我们资源包中的效果。效果如下:
然后还需要加一个Button
作为一个 开始按钮
那就来新建一个Button
,然后选择资源包中的这个Go
图片作为点击按钮,并将Button
下的Text
本文改为开始
。效果如下:
然后还可以给这个开始按钮加一个outline
和shadow
组件来做一个阴影效果!
如下所示:
然后我们可以在背景图bg
下面新建一些Image
加一些小图片做一个点缀效果
当然这不是必须要做的哈,知识单纯的让看起来可以更美观一些,要不然有些空空的
图片都是资源包中的,只需要更换一下图片素材就好了。效果如下:
🏳️🌈设置 开始场景 的 侧边栏
这个侧边栏会用来显示皮肤
、模式选择
和分数显示
,在一开始的游戏展示中我们也看到了,所以这里需要来设置一下
我们在ControPanle
下新建一个Text文本框
,输入皮肤两个字,然后调整一下字体大小和位置
如果不知道设置多少比较好,可以参考下我设置的,参数和效果如下:
然后照葫芦画瓢,继续加一个模式选择
和 分数显示
,效果如下:
三个标题添加好了,但是里面还有小标题,再来继续设置一下
先来设置一下分数
在分数Store
下新建一个Text
文本作为上次成。,输入:上次:长度0,分数0
然后调整一下大小和位置,参数和效果如下:
然后继续照葫芦画瓢,添加一个最好成绩,参数和效果如下:
然后接下来搞一下模式
的设置
我们在模式Mode
下新建一个Toggle选择框
,用于做模式选择
的时候使用
改一下名字为:Border
,然后设置一下文字大小等参数,效果如下:
然后照葫芦画瓢再来整一个自由模式
,参数效果如下:
这里只是为了做一个UI效果,具体怎样设置都可以,只是作为一个参考!
然后还没完,因为正常游戏中两种模式只能选择一个,所以我们在这里需要添加一个组件用于控制
那就是Toggle Group
组件,这是UGUI自带的一个组件,目的就是遇到这多个选择框只能选择一个的时候使用
我们给Mode对象身上添加一个Toggle Group组件
,然后在两个边界模式的Toggle组件
属性中的Group
设置成父物体身上的Toggle Group组件
,效果如下:
然后还有一个皮肤选择
没有设置,再来设置一下
同理也是需要添加一个Toggle
组件,然后设置一下位置和大小
然后我们对这个Toggle
组件做一个简单的配置,使用我们的素材给他装饰的好看一些
这一步也是自己看兴趣设置,哪怕使用一个默认的Toggle
组件不做装饰也是可以的!
配置好了之后如下图所示:
如果详细的配置信息没有看明白,可以结合后面的源码来进行更详细的参数设置
因为在文中可能有地方语言描述真的很费劲,所以结合源码工程观看,学习体验效果更佳!
然后照葫芦画瓢再来配置一个其他颜色的,直接复制一个,然后调整位置修改一下
如下所示:
然后同模式选择一样,皮肤也只能选择一个来进行游戏
所以这里还是需要添加一个Toggle Group
组件给Skin
对象添加上
然后给两个小蛇的对象Bule和yellow
的Group
属性中将父物体添加上,效果如下:
然后开始界面的UI基本上算是搭建完毕了,接下来就是下一步了!
🏳️🌈新建一个场景,设置 游戏场景 的界面
开始场景我们设置完了,还需要一个进行游戏的场景设置
我们在Sence文件夹
中新建一个场景Main
作为游戏场景
然后跟开始场景中一样,对侧边栏
进行设置,设置的参数和开始场景并没有很大的区别
直接来看一下我设置的即可,就是单纯的UI大小位置设置,查看更详细的设置参照源码即可,很简单就不赘述了!
🏳️🌈给游戏场景添加可视化边界
基本的游戏场景
设置完了,在我们的小蛇碰到边界的时候是会触发不同的效果的
- 在
边界模式
中,碰到边界就会死亡,结束游戏 - 在
自由模式
中,碰到边界会进行一个穿透传送效果
那接下来就来设置一下游戏的边界处理
我们在bg
下新建一个Image
作为上边界,给这个Image
添加一个碰撞体BoxCollider
然后调整图片和碰撞体的大小
参数和效果如下所示:
这里的话不同的电脑可能参数会有略微差异,根据自己的视图大小调整这个边界的位置和大小即可
最终效果是让这个游戏视图的上下所有边界都完整覆盖即可!如下所示:
🏳️🌈制作小蛇并让其移动
现在我们游戏场景有了,那接下来就需要一条小蛇来进行游戏了
所以我们在Canvas
下新建一个Image
命名为SnakeHead
并将我们素材中的一个小蛇头的图片拖上去
调整一下这个Image的大小为45即可,如下所示
然后就是编写一个SnakeHead脚本代码让小蛇动起来,新建一个脚本,将一下代码放进去即可!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SnakeHead : MonoBehaviour
{
public float velocity = 0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
void Start()
{
InvokeRepeating("Move", 0, velocity);
x = 0; y = step;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) )
{
CancelInvoke();
InvokeRepeating("Move", 0, velocity - 0.2f);
}
if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", 0, velocity);
}
if (Input.GetKey(KeyCode.W) && y != -step )
{
gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0);
x = 0; y = step;
}
if (Input.GetKey(KeyCode.S) && y != step )
{
gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180);
x = 0; y = -step;
}
if (Input.GetKey(KeyCode.A) && x != step )
{
gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90);
x = -step; y = 0;
}
if (Input.GetKey(KeyCode.D) && x != -step )
{
gameObject.transform.localRotation = Quaternion.Euler(0, 0, -90);
x = step; y = 0;
}
}
void Move()
{
headPos = gameObject.transform.localPosition; //保存下来蛇头移动前的位置
gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, headPos.z); //蛇头向期望位置移动
}
}
通过键盘按键来让小蛇进行不同方向的移动,并设置一个时间和一个移动速度即可,效果如下:
🏳️🌈随机生成食物、食物被吃掉 和 生成新的食物
现在小蛇可以进行移动了,还需要添加一个食物的自动生成
,所以再接着来做这个食物的随机生成
随机生成食物也很简单,先来判断一下食物可以生成的范围,肯定就是游戏边界内,不能生成到游戏场景外面
新建一个脚本 FoodMaker
用来随机生成一个食物
using UnityEngine;
using UnityEngine.UI;
public class FoodMaker : MonoBehaviour
{
public int xlimit = 21;
public int ylimit = 11;
public int xoffset = 7;
public GameObject foodPrefab;
public Sprite[] foodSprites;
private Transform foodHolder;
void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood();
}
public void MakeFood()
{
int index = Random.Range(0, foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder, false);
int x = Random.Range(-xlimit + xoffset, xlimit);
int y = Random.Range(-ylimit, ylimit);
food.transform.localPosition = new Vector3(x * 30, y * 30, 0);
}
}
使用ylimit 和xlimit
来控制一个随机生成的边界
通过foodSprites
数组来控制随机生成食物的图片
然后这样就可以随机生成食物了,后面会写方法,当小蛇吃掉一个食物的时候再生成新的食物就好了!
上面说了食物的一个随机生成
,那接下来要对食物被吃掉和生成一个新的食物来进行逻辑处理
我们要从蛇头这边来介入,因为只有当蛇头碰到食物之后,食物才会消失,是通过碰撞检测来完成的
所以要给蛇头添加一个碰撞体
和刚体
,来进行一个碰撞检测
!
然后在SnakeHead
脚本中添加代码用来检测食物
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
FoodMaker.Instance.MakeFood((Random.Range(0, 100) < 20) ? true : false);
}
}
这样的话当蛇头碰到食物之后,食物就会消失,然后调用生成食物的方法继续生成新的食物啦!
🏳️🌈小蛇吃食物变长 和 蛇身的移动
现在小蛇可以进行吃食物了,而且食物也会被吃掉之后随机生成新的,但是蛇身还没有变长
所以现在来写一下蛇身变长的逻辑和代码,还是在SnakeHead
脚本中添加代码
声明一个List
用来蛇身的处理,后续蛇身移动的时候会用到
public List<Transform> bodyList = new List<Transform>();
void Grow()
{
int index = (bodyList.Count % 2 == 0) ? 0 : 1;
GameObject body = Instantiate(bodyPrefab, new Vector3(2000, 2000, 0), Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
}
将这段代码在蛇吃到食物之后调用即可,这样的话就可以在吃到食物之后蛇身变长了!
然后是蛇身的移动代码,使用List
存储蛇身,然后让蛇身的每一个后边的蛇身位置换到蛇身前边的位置
这样就可以形成一个蛇不断移动的效果,蛇身的后一个节点和前一个节点之间就可以正常跟随蛇头移动了!
void Move()
{
headPos = gameObject.transform.localPosition; //保存下来蛇头移动前的位置
gameObject.transform.localPosition = new Vector3(headPos.x + x, headPos.y + y, headPos.z); //蛇头向期望位置移动
if (bodyList.Count > 0)
{
//由于我们是双色蛇身,使用此方法达到显示目的
for (int i = bodyList.Count - 2; i >= 0; i--) //从后往前开始移动蛇身
{
bodyList[i + 1].localPosition = bodyList[i].localPosition; //每一个蛇身都移动到它前面一个节点的位置
}
bodyList[0].localPosition = headPos; //第一个蛇身移动到蛇头移动前的位置
}
}
🏳️🌈蛇身边界传送效果
在边界模式
下,当蛇碰到边界时就是触发死亡,这个操作很简单
我们在边界设置了碰撞体
,所以当蛇碰到边界时就会触发一个回调
因为我们蛇身移动的逻辑是跟随前一个结点移动,所以只需要蛇头的边界传送,蛇身就会自动跟随达到我们想要的效果
所以我们只需要判断蛇头到达边界的时候,改动一下蛇头的位置就好了!
还是在SnakeHead
脚本中添加代码,关键代码如下
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
FoodMaker.Instance.MakeFood((Random.Range(0, 100) < 20) ? true : false);
}
else
{
switch (collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + 30, transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 30, transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x + 180, transform.localPosition.y, transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x + 240, transform.localPosition.y, transform.localPosition.z);
break;
}
}
}
🏳️🌈分数和长度的记录
现在蛇的基本移动
、变长
和食物生成
等等都做好了
那接下来就是分数的增加
了,只需要在吃掉食物的时候调用一下就好了!
新建一个脚本MainUIController
,用于 控制分数的增加
和 等级的判定
代码也很简单,当吃掉食物就进行调用即可!
public int score = 0;
public int length = 0;
public Text scoreText;
public Text lengthText;
public void UpdateUI(int s = 5, int l = 1)
{
score += s;
length += l;
scoreText.text = "得分:\n" + score;
lengthText.text = "长度:\n" + length;
}
然后在这个脚本中在写一下根据不同的分数阶段,进行场景背景的一个变化
这就是一个游戏玩法
的增加了,代码如下:
switch (score / 100)
{
case 0:
case 1:
case 2:
break;
case 3:
case 4:
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 2;
break;
case 5:
case 6:
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 3;
break;
case 7:
case 8:
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 4;
break;
case 9:
case 10:
ColorUtility.TryParseHtmlString("#FFF3CCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 5;
break;
default:
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "无尽阶段";
break;
}
🏳️🌈游戏暂停 和 菜单键 的设置
到这里的话游戏基本功能
就是完成了,这一步是将游戏场景中的暂停键
和返回菜单键
的功能给加上
之前知识添加了UI,并没有写实际的方法,所以这里给加上
还是在MainUIController
脚本进行编写代码,因为MainUIController
脚本就是一个处理UI相关内容的
public void Pause()
{
isPause = !isPause;
if (isPause)
{
Time.timeScale = 0;
pauseImage.sprite = pauseSprites[1];
}
else
{
Time.timeScale = 1;
pauseImage.sprite = pauseSprites[0];
}
}
public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene(0);
}
很简单就可以实现暂停和返回菜单的功能实现了!
🏳️🌈蛇死亡的处理 和 游戏得分记录
小蛇在游戏结束时要记录一个游戏得分
,和一个游戏结束的效果
在SnakeHead
脚本中写一个Die
方法
void Die()
{
isDie = true;
Instantiate(dieEffect);
PlayerPrefs.SetInt("lastl", MainUIController.Instance.length);
PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
if (PlayerPrefs.GetInt("bests", 0) < MainUIController.Instance.score)
{
PlayerPrefs.SetInt("bestl", MainUIController.Instance.length);
PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
}
StartCoroutine(GameOver(1.5f));
}
这里使用PlayerPrefs
存储一个分数数据给简单存储起来即可,然后死亡的时候释放一个死亡特效
在小蛇撞到边界和蛇身的时候调用即可!
🏳️🌈用户的设置和储存
我们需要在开始界面中显示模式的选择
和 小蛇皮肤
的选择,还有上次游戏的分数
和 最高分数
的存储`
新建一个脚本StartUIController
,挂在场景中即可
using UnityEngine;
using UnityEngine.UI;
public class StartUIController : MonoBehaviour
{
public Text lastText;
public Text bestText;
public Toggle blue;
public Toggle yellow;
public Toggle border;
public Toggle noBorder;
void Awake()
{
lastText.text = "上次:长度" + PlayerPrefs.GetInt("lastl", 0) + ",分数" + PlayerPrefs.GetInt("lasts", 0);
bestText.text = "最好:长度" + PlayerPrefs.GetInt("bestl", 0) + ",分数" + PlayerPrefs.GetInt("bests", 0);
}
void Start()
{
if (PlayerPrefs.GetString("sh", "sh01") == "sh01")
{
blue.isOn = true;
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
else
{
yellow.isOn = true;
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
if (PlayerPrefs.GetInt("border", 1) == 1)
{
border.isOn = true;
PlayerPrefs.SetInt("border", 1);
}
else
{
noBorder.isOn = true;
PlayerPrefs.SetInt("border", 0);
}
}
public void BlueSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
}
public void YellowSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
}
public void BorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border", 1);
}
}
public void NoBorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border", 0);
}
}
public void StartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene(1);
}
}
这样的话用户选择的 小蛇的皮肤
和 模式的选择
就可以带入到游戏场景中了!
🏳️🌈游戏打包及发布
游戏都做好啦,我们可以打包
成一个PC端的游戏进行玩耍!
打包程序也很简单,File -> Build Setting -> Player Setting
然后设置一下游戏图标
和游戏名字
,点击 Build
选择一个文件夹即可!
Build
结束之后,就会在选择的文件夹中出现这样几个文件
我们点击这个小蛇的头像的exe文件
就可以直接玩游戏啦!
🎄源码展示
由于本工程实际只有四个脚本
完成,所以为了方便看代码学习,直接将所有代码展示出来
省的还需要打开Unity工程才能查看了
StartUIController脚本 :用于控制开始场景中的控制器
using UnityEngine;
using UnityEngine.UI;
public class StartUIController : MonoBehaviour
{
public Text lastText;
public Text bestText;
public Toggle blue;
public Toggle yellow;
public Toggle border;
public Toggle noBorder;
void Awake()
{
lastText.text = "上次:长度" + PlayerPrefs.GetInt("lastl", 0) + ",分数" + PlayerPrefs.GetInt("lasts", 0);
bestText.text = "最好:长度" + PlayerPrefs.GetInt("bestl", 0) + ",分数" + PlayerPrefs.GetInt("bests", 0);
}
void Start()
{
if (PlayerPrefs.GetString("sh", "sh01") == "sh01")
{
blue.isOn = true;
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
else
{
yellow.isOn = true;
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
if (PlayerPrefs.GetInt("border", 1) == 1)
{
border.isOn = true;
PlayerPrefs.SetInt("border", 1);
}
else
{
noBorder.isOn = true;
PlayerPrefs.SetInt("border", 0);
}
}
public void BlueSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
}
public void YellowSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
}
public void BorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border", 1);
}
}
public void NoBorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border", 0);
}
}
public void StartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene(1);
}
}
MainUIController脚本:用于控制游戏场景中的UI显示控制
using UnityEngine;
using UnityEngine.UI;
public class MainUIController : MonoBehaviour
{
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
}
public bool hasBorder = true;
public bool isPause = false;
public int score = 0;
public int length = 0;
public Text msgText;
public Text scoreText;
public Text lengthText;
public Image pauseImage;
public Sprite[] pauseSprites;
public Image bgImage;
private Color tempColor;
void Awake()
{
_instance = this;
}
void Start()
{
if (PlayerPrefs.GetInt("border", 1) == 0)
{
hasBorder = false;
foreach (Transform t in bgImage.gameObject.transform)
{
t.gameObject.GetComponent<Image>().enabled = false;
}
}
}
void Update()
{
switch (score / 100)
{
case 0:
case 1:
case 2:
break;
case 3:
case 4:
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 2;
break;
case 5:
case 6:
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 3;
break;
case 7:
case 8:
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 4;
break;
case 9:
case 10:
ColorUtility.TryParseHtmlString("#FFF3CCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + 5;
break;
default:
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "无尽阶段";
break;
}
}
public void UpdateUI(int s = 5, int l = 1)
{
score += s;
length += l;
scoreText.text = "得分:\n" + score;
lengthText.text = "长度:\n" + length;
}
public void Pause()
{
isPause = !isPause;
if (isPause)
{
Time.timeScale = 0;
pauseImage.sprite = pauseSprites[1];
}
else
{
Time.timeScale = 1;
pauseImage.sprite = pauseSprites[0];
}
}
public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene(0);
}
}
FoodMaker脚本:用于控制食物的管理
using UnityEngine;
using UnityEngine.UI;
public class FoodMaker : MonoBehaviour
{
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = 21;
public int ylimit = 11;
public int xoffset = 7;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder;
void Awake()
{
_instance = this;
}
void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
}
public void MakeFood(bool isReward)
{
int index = Random.Range(0, foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder, false);
int x = Random.Range(-xlimit + xoffset, xlimit);
int y = Random.Range(-ylimit, ylimit);
food.transform.localPosition = new Vector3(x * 30, y * 30, 0);
if (isReward)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * 30, y * 30, 0);
}
}
}
🎁游戏源码下载 和 效果展示
这里我把游戏的源码工程 、素材和打包好的exe文件统一放到一个压缩包中
有需要的小伙伴点击链接下载就好, 如果积分不够的小伙伴私信我也可以
我看到的时候就会发给你了啦!
贪吃蛇下载链接:https://download.csdn.net/download/zhangay1998/22490642
完整效果展示:
👥总结
-
本篇文章对 贪吃蛇小游戏做了一个详细的说明教程
-
看起来挺多的,实际上只有 四个脚本 就可以完成这个游戏了
-
源码也只不过 10M多点大小 ,只是制作过程稍微繁琐了一些,但是都是基础内容很适合新手学习!
-
如果在看的过程中有哪一步没看懂或者博主没有说到,那可以结合源码工程观看即可!
-
因为在文中可能有地方语言描述真的很费劲,所以结合源码工程观看,学习体验效果更佳!
-
博主辛苦写文不宜,大家可以粉红色三连一波支持博主呀!
🚀往期优质文章分享
- ❤️Unity零基础到入门 | 游戏引擎 Unity 从0到1的 系统学习 路线【全面总结-建议收藏】!
- 🧡花一天时间做一个高质量飞机大战游戏,过万字Unity完整教程!漂亮学妹看了直呼666!
- 💛回忆童年和小伙伴一起玩过的经典游戏【炸弹人小游戏】制作过程+解析
- 💚通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难
- 🤍爆肝整整一个周末写一款类似 皇室战争 的 即时战斗类 游戏Demo!两万多字游戏制作过程+解析!
- 💙一款类似“恐龙快打”的 横版街机格斗游戏 该如何制作?| 一起来学习 顺便送源码【码文不易,建议收藏学习】
- 💜【超实用技巧】| 提高写文的质量 和 速率必学技能: Typora 图床配置 详细说明
🚀 优质专栏分享 🚀 |
- 🎄如果感觉文章看完了不过瘾,可以来我的其他 专栏 看一下哦~
- 🎄比如以下几个专栏:Unity基础知识学习专栏、Unity游戏制作专栏、Unity实战类项目 和 算法学习专栏
- 🎄可以学习更多的关于Unity引擎的相关内容哦!直接点击下面颜色字体就可以跳转啦!