Unity3D_(游戏)贪吃蛇
Unity制作贪吃蛇小游戏
玩家通过“WASD”控制小蛇上下左右移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束
可通过游戏开始前对小蛇皮肤进行选择
自由模式下蛇头可以穿过四周的墙
使用本地持久化保存与读取的类——PlayerPrefs类对玩家游戏数据的存储
PlayerPrefs类存储位置 传送门
Unity圣典 传送门
游戏项目已托管到Github上 传送门
游戏展示
对玩家的游戏数据记录
游戏界面存储玩家最高分以及上一次游戏的分数
游戏换肤
为玩家可以选择蓝色小蛇或黄色小蛇
游戏模式
边界模式下蛇撞到边界判定游戏结束
自由模式下蛇碰到边界时会从另一个边界线出来
(文字最下边有游戏脚本源代码)
实现过程
制作开始场景UI界面
添加一个Canvas作为游戏开始场景并将Canvas下的Render Mode设置为Screen Space—Camera
- 1:Screen Space-Overlay:这种模式层级视图中不需要任何的摄像机,且UI出现在所有摄像机的最前面。
- 2:Screen Space-Camera:这种模式需要绑定一个UICamrea,它支持UI前面显示3D对象和粒子系统。
- 3:World Space:这种模式,UI和3d对象完全一样。
Canvas 三种渲染模式如下
(2D游戏常用Screen Space-Camera模式,3D游戏常用Screen Space-Overlay模式)
Canvas Scaler(Script)个人比较喜欢设置UI Scale Mode设置成Scale With Screen Si 根据屏幕尺寸来调整UI的缩放值
指定渲染摄像机
添加游戏背景及控制面板
使用UGUI制作游戏场景界面
Bg(Image):制作游戏背景界面
ControlPanel(Panel):制作游戏选项区域
Title(Text):制作游戏标题
Go(Image):制作游戏开始图标
添加Button控件,制作成按钮
添加Outline外边框和Shadow阴影组件(逼真图片按钮)
Text:"开始"文本
添加十张Image作为游戏背景图片
食物作为游戏背景太鲜明时,可以把食物的透明度调为150
制作Text文字背景
Mode下添加一个Toggle提供玩家对模式的选择
(给文字添加Outline给玩家一种朦胧感)
边界模式下,蛇撞墙后判断游戏结束
复制边界模式Toggle,修改文字为自由模式(自由模式下蛇撞墙后不会判定结束游戏)
边界模式和自由模式玩家只能选择一个
给Mode添加Toggle Group组件
将Toggle Group组件绑定给Border和NoBorder
is on :当前标签是否勾选
同理添加小蛇皮肤属性
将选择小蛇皮肤也设置成Toggle Group
"黄色小蛇"和"自由模式" is on 去掉勾选
游戏场景UI界面
ControlPanel下的按钮、文本控件
Msg(Text):玩家选择游戏模式
Score(Text):玩家当前得分
Length(Text):当前蛇自身长度
Home(Image):返回主页面按钮
Pause(Image):停止游戏按钮
给游戏场景添加边界
Bg下创建两个GameObject,设置(锚点)GameObject范围,添加Box Collider 2D作为游戏碰撞器
给小蛇添加活动范围,添加一个Box Collider 2D碰撞器
为了将活动范围标记出来,可以给碰撞其添加一个Image红色图片作为围墙
修改一下碰撞器范围
制作贪吃蛇舌头并让其移动
添加Image制作舌头,设置好舌头大小
创建SnakeHead.cs脚本并绑定到蛇头部
控制小蛇头部移动脚本
- void Move()
- {
- headPos = gameObject.transform.localPosition;
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- }
添加键盘按钮事件
- private void Update()
- {
- if (Input.GetKey(KeyCode.W))
- {
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S))
- {
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A))
- {
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D))
- {
- x = step;y = ;
- }
- }
初始时及改变方向时不断让小蛇向着一个方向移动
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = step;y = ;
- }
- Invoke() 方法是 Unity3D 的一种委托机制
- 如: Invoke("Test", ); 它的意思是: 秒之后调用 Test() 方法;
- 使用 Invoke() 方法需要注意 3点:
- :它应该在 脚本的生命周期里的(Start、Update、OnGUI、FixedUpdate、LateUpdate)中被调用;
- :Invoke(); 不能接受含有参数的方法;
- :在 Time.ScaleTime = ; 时, Invoke() 无效,因为它不会被调用到
- Invoke() 也支持重复调用:InvokeRepeating("Test", , );
- 这个方法的意思是指: 秒后调用 Test() 方法,并且之后每隔 秒调用一次 Test() 方法
- 还有两个重要的方法:
- IsInvoking:用来判断某方法是否被延时,即将执行
- CancelInvoke:取消该脚本上的所有延时方法
Unity中Invoke 和 InvokeRepeating的区别
- 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;
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = step;y = ;
- }
- private void Update()
- {
- if (Input.GetKey(KeyCode.W))
- {
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S))
- {
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A))
- {
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D))
- {
- x = step;y = ;
- }
- }
- void Move()
- {
- headPos = gameObject.transform.localPosition;
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- }
- }
SnakeHead.cs
给小蛇头部添加转动时改变头部方向动画
- private void Update()
- {
- if (Input.GetKey(KeyCode.W))
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S))
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A))
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D))
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
发现小球向左走时还能向右走,向下走时还能向上走
判断按键方法时候可以对方向进行一个判断
- private void Update()
- {
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
添加按下空格加快贪吃蛇向前移动速度
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.2f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
Unity圣典 传送门
MonoBehaviour.CancelInvoke 取消调用
MonoBehaviour.InvokeRepeating 重复调用
- 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;
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.2f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- headPos = gameObject.transform.localPosition;
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- }
- }
SnakeHead.cs
第一个食物的随机生成
对游戏边界范围的判定
上边界与下边界
经测试
小蛇走11步碰到上边界,走10步碰到下边界
小蛇走19步碰到右边界,走11步碰到左边界
将食物和小蛇设置为预制体
创建一个GameObject空物体对象挂在脚本和预制体
游戏初始时获得游戏物体,并且生成食物
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood();
- }
随机生成食物的位置
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- void MakeFood()
- {
- //生成x和y的随机值
- int x = Random.Range(-xlimit + xoffset,xlimit);
- int y = Random.Range(-ylimit,ylimit);
- //通过小蛇自身的步数长度来计算食物的活动空间
- food.transform.localPosition = new Vector3(x * , y * , );
- }
随机生成食物的种类和位置
- void MakeFood()
- {
- int index = Random.Range(,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 * , y * , );
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood();
- }
- void MakeFood()
- {
- int index = Random.Range(,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 * , y * , );
- }
- }
FoodMaker.cs
- 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;
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.2f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- headPos = gameObject.transform.localPosition;
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- }
- }
SnakeHead.cs
吃掉食物(销毁)以及食物的随机生成
给蛇头添加Box Collider 2D碰撞器,为避免蛇头未碰撞食物时碰撞器就碰撞到食物,可以设置碰撞器范围比蛇头小一圈
勾选Is Trigger,当物体碰到食物及边界时,可以进入边界再判定游戏结束
给蛇头添加Rigidbody 2D碰撞器,设置重力 Gravity Scale为0 (不然蛇头在开始游戏时就会不断往下掉)
同理,给食物预设体Food添加Box Collider 2D碰撞器
新创建一个Food标签作为标记
将Food预设体标签设置为Food
SnakeHead.cs中添加食物碰撞生成新食物方法
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- FoodMaker.Instance.MakeFood();
- }
- }
FoodMaker.cs
添加一个单例模式
- //单例模式
- private static FoodMaker _instance;
- //可以通过外部去调用方法修改_instance的值
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- //初始化
- private void Awake()
- {
- _instance = this;
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood();
- }
- public void MakeFood()
- {
- int index = Random.Range(,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 * , y * , );
- }
- }
FoodMaker.cs
- 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;
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.2f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- headPos = gameObject.transform.localPosition;
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- FoodMaker.Instance.MakeFood();
- }
- }
- }
SnakeHead.cs
蛇身吃掉食物的变长
添加一个Image放置蛇身图片,添加Box Collider 2D碰撞器(碰撞器的范围不用太大,以免对食物产生不可描述的误操作)
SnakeHead.cs脚本中生成蛇身
创建一个集合,用来保存蛇身部分(两张图片不断轮流交换)
- public List<RectTransform> bodyList = new List<RectTransform>();
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
生成蛇身体方法
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas,false);
- bodyList.Add(body.transform);
- }
蛇生体移动的方法
创建一个链表,当蛇吃了食物后,将蛇身放置到链表中
- public List<Transform> bodyList = new List<Transform>();
将图片放置到bodySprites中(两张),存放的都是bodyPrefab
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- }
Unity中将预制体与贪吃蛇头部绑定一下
蛇碰到食物后开始生成蛇身
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- Grow();
- FoodMaker.Instance.MakeFood();
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood();
- }
- public void MakeFood()
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- }
- }
FoodMaker.cs
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- Grow();
- FoodMaker.Instance.MakeFood();
- }
- }
- }
SnakeHead.cs
游戏的自由模式
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到下边界时再往上走一步后从上边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
- switch(collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
- break;
- }
奖励目标的生成
添加一个Reward(Image)作为奖励目标背景图片
调整奖励背景图片和食物大小保持一样,并添加Box Collider 2D组件
将Resward作为预制体
FoodMaker.cs上绑定rewardPrefabs预制体
- public GameObject rewardPrefab;
判断是否生成道具
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
当蛇吃到食物后,有百分之20的机率生成道具
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
当蛇吃到道具时,道具销毁
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- Grow();
- }
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- Grow();
- }
- else if(collision.gameObject.CompareTag("Body"))
- {
- Debug.Log("Die");
- }
- else
- {
- switch(collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- }
- }
SnakeHead.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public GameObject rewardPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood(false);
- }
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
- }
FoodMaker.cs
分数与长度与游戏背景切换
新建一个脚本MainUIController.cs来存储蛇的分数与长度
分数的单例模式
- //单例模式
- private static MainUIController _instance;
- public static MainUIController Instance
- {
- get
- {
- return _instance;
- }
- }
游戏加分方法 默认吃到一个食物加5分1个长度 获得道具加分会更高
- public void UpdateUI(int s = ,int l = )
- {
- score += s;
- length += l;
- scoreText.text ="得分:\n"+score;
- lengthText.text = "长度\n" + length;
- }
当蛇吃到食物或道具时调用UpdateUI()方法
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI();
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI(Random.Range(,)*);
- Grow();
- }
当分数达到一定数值时能进行游戏背景变色
- private void Update()
- {
- switch (score / )
- {
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
- bgImage.color=tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段 x";
- break;
- }
- }
将脚本放在Script游戏物体上,并绑定分数版、背景等
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space))
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step )
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI();
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI(Random.Range(,)*);
- Grow();
- }
- else if(collision.gameObject.CompareTag("Body"))
- {
- Debug.Log("Die");
- }
- else
- {
- switch(collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- }
- }
SnakeHead.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public GameObject rewardPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood(false);
- }
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
- }
FoodMaker.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class MainUIController : MonoBehaviour {
- //单例模式
- private static MainUIController _instance;
- public static MainUIController Instance
- {
- get
- {
- return _instance;
- }
- }
- public int score = ;
- public int length = ;
- public Text msgText;
- public Text scoreText;
- public Text lengthText;
- public Image bgImage;
- private Color tempColor;
- void Awake()
- {
- _instance = this;
- }
- private void Update()
- {
- switch (score / )
- {
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
- bgImage.color=tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段 x";
- break;
- }
- }
- public void UpdateUI(int s = ,int l = )
- {
- score += s;
- length += l;
- scoreText.text ="得分:\n"+score;
- lengthText.text = "长度\n" + length;
- }
- }
MainUIController.cs
暂停与返回按钮
对按钮进行引用以及添加一个图片Sprite[]
- public Button pauseButton;
- public Sprite[] pauseSprites;
设置一个变量记录游戏状态
- private bool isPause = false ;
点击按钮时候对游戏状态取反
- public void Pause()
- {
- isPause = !isPause;
- if(isPause)
- {
- Time.timeScale = ;
- pauseButton.GetComponent<Image>().sprite = pauseSprites[];
- }
- else
- {
- Time.timeScale = ;
- pauseButton.GetComponent<Image>().sprite = pauseSprites[];
- }
- }
Time.timeScale 传送门
Script中对图片、按钮进行绑定
在onclick()
解决按键冲突
按键控制器Edit->Project Settings-> Input
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false)
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false)
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
Update()中对键盘按下事件进行处理
接下来实现返回按钮
- public void Home()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
Home按钮上添加点击事件
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false)
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false)
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI();
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI(Random.Range(,)*);
- Grow();
- }
- else if(collision.gameObject.CompareTag("Body"))
- {
- Debug.Log("Die");
- }
- else
- {
- switch(collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- }
- }
SnakeHead.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public GameObject rewardPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood(false);
- }
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
- public void Home()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- }
FoodMaker.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class MainUIController : MonoBehaviour {
- //单例模式
- private static MainUIController _instance;
- public static MainUIController Instance
- {
- get
- {
- return _instance;
- }
- }
- public int score = ;
- public int length = ;
- public Text msgText;
- public Text scoreText;
- public Text lengthText;
- public Image bgImage;
- private Color tempColor;
- public Image pauseImage;
- public Sprite[] pauseSprites;
- public bool isPause = false ;
- void Awake()
- {
- _instance = this;
- }
- private void Update()
- {
- switch (score / )
- {
- case :
- case :
- case :
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
- bgImage.color=tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- case :
- ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段 x";
- break;
- }
- }
- public void UpdateUI(int s = ,int l = )
- {
- score += s;
- length += l;
- scoreText.text ="得分:\n"+score;
- lengthText.text = "长度\n" + length;
- }
- public void Pause()
- {
- isPause = !isPause;
- if(isPause)
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- else
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- }
- }
MainUIController.cs
游戏贪吃蛇死亡处理
添加游戏死亡标记
- private bool isDie = false;
判断游戏死亡时触发的粒子特效
- void Die()
- {
- CancelInvoke();
- isDie = true;
- Instantiate(dieEffect);
- StartCoroutine(GameOver(1.0f));
- }
通过Unity协成进行游戏的重新开始
- IEnumerator GameOver(float t)
- {
- yield return new WaitForSeconds(t);
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
游戏结束时候记录最高得分
- void Die()
- {
- CancelInvoke();
- isDie = true;
- Instantiate(dieEffect);
- //记录游戏的最后长度
- PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
- PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
- //当游戏长度大于最高得分时
- if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
- {
- //将当前游戏长度和分数记录到best1和bests当中
- PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
- PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
- }
- StartCoroutine(GameOver(1.0f));
- }
- 1、存储值://本地化存储方式,一般用在保存玩家的偏好设置中,常见于玩家设置,游戏分数存取…………
- PlayerPrefs.SetFloat(string key,float value); //通过key 与value 存储,就像键值对一样。
- PlayerPrefs.SetInt(string key,Int value);
- PlayerPrefs.SetString(string key,string value);
- 2、读取值:
- PlayerPrefs.GetFloat(string key); //通过key得到存储的value值
- PlayerPrefs.GetInt(string key);
- PlayerPrefs.GetString(string key);
Unity 中PlayerPrefs类实现数据本地化存储
用户设置的存储
添加StartUIController.cs脚本控制Gary开始场景界面
获得Gary开始场景界面Text文本控件
- public Text lastText;
- public Text bestText;
对文本控件的值进行读取刷新
- private void Awake()
- {
- lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",0) + ",分数" + PlayerPrefs.GetInt("lasts",0);
- lastText.text = "最好:长度" + PlayerPrefs.GetInt("best1", 0) + ",分数" + PlayerPrefs.GetInt("bests", 0);
- }
Gary场景中创建一个空物体游戏对象ScriptHolder挂在游戏脚本
实现点击开始进入场景功能
切换场景方法
- public void StartGame()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene(1);
- }
Gary场景中Start添加onClick()点击事件
(可以看到此时已经实现上次分数以及最高分数的存储)
动态绑定选择游戏皮肤、模式
存储玩家的选择
- private 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);
- }
- }
完成换肤与数据读取
使用泛型加载游戏换肤方法
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- //通过Resources.Load(string path)方法加载资源;
- gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh01", "sh0201"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh02", "sh0202"));
- }
判断游戏模式
添加一个模式表示位
- public bool hasBorder = true;
游戏初始时默认无边界
- void Start()
- {
- if (PlayerPrefs.GetInt("border", )==)
- {
- hasBorder = false;
- //取消边界上的颜色
- foreach(Transform t in bgImage.gameObject.transform)
- {
- t.gameObject.GetComponent<Image>().enabled = false;
- }
- }
- }
SnakeHead.cs脚本中对游戏碰到边界死亡进行判定
- if (MainUIController.Instance.hasBorder)
- {
- Die();
- }
- else
- {
- switch (collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- using System.Collections;
- using System.Collections.Generic;
- 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;
- private void Awake()
- {
- lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",) + ",分数" + PlayerPrefs.GetInt("lasts",);
- bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", ) + ",分数" + PlayerPrefs.GetInt("bests",);
- }
- private 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", ) == )
- {
- border.isOn = true;
- PlayerPrefs.SetInt("border",);
- }
- else
- {
- noborder.isOn = true;
- PlayerPrefs.SetInt("border", );
- }
- }
- 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",);
- }
- }
- public void NoBorderSelected(bool isOn)
- {
- if (isOn)
- {
- //自由模式
- PlayerPrefs.SetInt("border", );
- }
- }
- public void StartGame()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- }
StartUIController.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class MainUIController : MonoBehaviour {
- //单例模式
- private static MainUIController _instance;
- public static MainUIController Instance
- {
- get
- {
- return _instance;
- }
- }
- public int score = ;
- public int length = ;
- public Text msgText;
- public Text scoreText;
- public Text lengthText;
- public Image bgImage;
- private Color tempColor;
- public Image pauseImage;
- public Sprite[] pauseSprites;
- public bool isPause = false ;
- public bool hasBorder = true;
- void Awake()
- {
- _instance = this;
- }
- void Start()
- {
- if (PlayerPrefs.GetInt("border", )==)
- {
- hasBorder = false;
- //取消边界上的颜色
- foreach(Transform t in bgImage.gameObject.transform)
- {
- t.gameObject.GetComponent<Image>().enabled = false;
- }
- }
- }
- private void Update()
- {
- switch (score / )
- {
- case :
- case :
- case :
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
- bgImage.color=tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- case :
- ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段 x";
- break;
- }
- }
- public void UpdateUI(int s = ,int l = )
- {
- score += s;
- length += l;
- scoreText.text ="得分:\n"+score;
- lengthText.text = "长度\n" + length;
- }
- public void Pause()
- {
- isPause = !isPause;
- if(isPause)
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- else
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- }
- }
MainUIController.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public GameObject rewardPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood(false);
- }
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
- public void Home()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- }
FoodMaker.cs
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- private bool isDie = false;
- public GameObject dieEffect;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- //通过Resources.Load(string path)方法加载资源;
- gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202"));
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false)
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false)
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- void Die()
- {
- CancelInvoke();
- isDie = true;
- Instantiate(dieEffect);
- //记录游戏的最后长度
- PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
- PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
- //当游戏长度大于最高得分时
- if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
- {
- //将当前游戏长度和分数记录到best1和bests当中
- PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
- PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
- }
- StartCoroutine(GameOver(1.0f));
- }
- IEnumerator GameOver(float t)
- {
- yield return new WaitForSeconds(t);
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI();
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI(Random.Range(,)*);
- Grow();
- }
- else if(collision.gameObject.CompareTag("Body"))
- {
- Die();
- }
- else
- {
- if (MainUIController.Instance.hasBorder)
- {
- Die();
- }
- else
- {
- switch (collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- }
- }
- }
SnakeHead.cs
添加游戏音乐
Main场景摄像机上绑定一个Audio Source音乐播放器
吃到东西和游戏结束时分别播放两个不同的音乐
- public AudioClip eatClip;
- public AudioClip dieClip;
- void Grow()
- {
- //播放贪吃蛇变长音乐
- AudioSource.PlayClipAtPoint(eatClip,Vector3.zero);
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- void Die()
- {
- //播放死亡音乐
- AudioSource.PlayClipAtPoint(dieClip, Vector3.zero);
- CancelInvoke();
- isDie = true;
- Instantiate(dieEffect);
- //记录游戏的最后长度
- PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
- PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
- //当游戏长度大于最高得分时
- if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
- {
- //将当前游戏长度和分数记录到best1和bests当中
- PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
- PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
- }
- StartCoroutine(GameOver(1.0f));
- }
游戏源代码
控制蛇和食物脚本
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.UI;
- public class SnakeHead : MonoBehaviour {
- public List<Transform> bodyList = new List<Transform>();
- public float velocity=0.35f;
- public int step;
- private int x;
- private int y;
- private Vector3 headPos;
- private Transform canvas;
- private bool isDie = false;
- public AudioClip eatClip;
- public AudioClip dieClip;
- public GameObject dieEffect;
- public GameObject bodyPrefab;
- public Sprite[] bodySprites = new Sprite[];
- private void Awake()
- {
- canvas = GameObject.Find("Canvas").transform;
- //通过Resources.Load(string path)方法加载资源;
- gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201"));
- bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202"));
- }
- private void Start()
- {
- //重复调用
- InvokeRepeating("Move",,velocity);
- x = ;y = step;
- }
- private void Update()
- {
- if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false)
- {
- CancelInvoke();
- InvokeRepeating("Move",,velocity - 0.3f);
- }
- if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false)
- {
- CancelInvoke();
- InvokeRepeating("Move", , velocity);
- }
- if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = step;
- }
- if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = ;y = -step;
- }
- if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , );
- x = -step;y = ;
- }
- if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false)
- {
- gameObject.transform.localRotation = Quaternion.Euler(, , -);
- x = step;y = ;
- }
- }
- void Move()
- {
- //保存下来蛇头移动前的位置
- headPos = gameObject.transform.localPosition;
- //蛇头向期望位置移动
- gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
- if (bodyList.Count > )
- {
- //由于是双色蛇身,此方法弃用
- //将蛇尾移动到蛇头移动前的位置
- // bodyList.Last().localPosition = headPos;
- //将蛇尾在List中的位置跟新到最前
- // bodyList.Insert(0, bodyList.Last());
- //溢出List最末尾的蛇尾引用
- // bodyList.RemoveAt(bodyList.Count - 1);
- //从后面开始移动蛇身
- for(int i =bodyList.Count-;i>= ;i--)
- {
- //每一个蛇身都移动到它前面一个
- bodyList[i + ].localPosition = bodyList[i].localPosition;
- }
- //第一个蛇身移动到蛇头移动前的位置
- bodyList[].localPosition = headPos;
- }
- }
- void Grow()
- {
- //播放贪吃蛇变长音乐
- AudioSource.PlayClipAtPoint(eatClip,Vector3.zero);
- int index = (bodyList.Count % == ) ? : ;
- GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
- body.GetComponent<Image>().sprite = bodySprites[index];
- body.transform.SetParent(canvas, false);
- bodyList.Add(body.transform);
- }
- void Die()
- {
- //播放死亡音乐
- AudioSource.PlayClipAtPoint(dieClip, Vector3.zero);
- CancelInvoke();
- isDie = true;
- Instantiate(dieEffect);
- //记录游戏的最后长度
- PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
- PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
- //当游戏长度大于最高得分时
- if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
- {
- //将当前游戏长度和分数记录到best1和bests当中
- PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
- PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
- }
- StartCoroutine(GameOver(1.0f));
- }
- IEnumerator GameOver(float t)
- {
- yield return new WaitForSeconds(t);
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- private void OnTriggerEnter2D(Collider2D collision)
- {
- if (collision.gameObject.CompareTag("Food"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI();
- Grow();
- if (Random.Range(,)<)
- {
- FoodMaker.Instance.MakeFood(true);
- }
- else
- {
- FoodMaker.Instance.MakeFood(false);
- }
- }
- else if(collision.gameObject.CompareTag("Reward"))
- {
- Destroy(collision.gameObject);
- MainUIController.Instance.UpdateUI(Random.Range(,)*);
- Grow();
- }
- else if(collision.gameObject.CompareTag("Body"))
- {
- Die();
- }
- else
- {
- if (MainUIController.Instance.hasBorder)
- {
- Die();
- }
- else
- {
- switch (collision.gameObject.name)
- {
- case "Up":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
- break;
- case "Down":
- transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
- break;
- case "Left":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- case "Right":
- transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
- break;
- }
- }
- }
- }
- }
SnakeHead.cs
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class FoodMaker : MonoBehaviour {
- //单例模式
- private static FoodMaker _instance;
- public static FoodMaker Instance
- {
- get
- {
- return _instance;
- }
- }
- public int xlimit = ;
- public int ylimit = ;
- //x轴活动空间不对称问题,对x轴的偏移值
- public int xoffset = ;
- public GameObject foodPrefab;
- public GameObject rewardPrefab;
- public Sprite[] foodSprites;
- private Transform foodHolder;
- private void Awake()
- {
- _instance = this;
- }
- private void Start()
- {
- foodHolder = GameObject.Find("FoodHolder").transform;
- MakeFood(false);
- }
- public void MakeFood(bool isReward)
- {
- int index = Random.Range(,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 * , y * , );
- //food.transform.localPosition = new Vector3( x, y, 0);
- if(isReward==true)
- {
- 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 * , y * , );
- }
- }
- public void Home()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- }
FoodMaker.cs
场景UI控制脚本
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- public class MainUIController : MonoBehaviour {
- //单例模式
- private static MainUIController _instance;
- public static MainUIController Instance
- {
- get
- {
- return _instance;
- }
- }
- public int score = ;
- public int length = ;
- public Text msgText;
- public Text scoreText;
- public Text lengthText;
- public Image bgImage;
- private Color tempColor;
- public Image pauseImage;
- public Sprite[] pauseSprites;
- public bool isPause = false ;
- public bool hasBorder = true;
- void Awake()
- {
- _instance = this;
- }
- void Start()
- {
- if (PlayerPrefs.GetInt("border", )==)
- {
- hasBorder = false;
- //取消边界上的颜色
- foreach(Transform t in bgImage.gameObject.transform)
- {
- t.gameObject.GetComponent<Image>().enabled = false;
- }
- }
- }
- private void Update()
- {
- switch (score / )
- {
- case :
- case :
- case :
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
- bgImage.color=tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段" + ;
- break;
- case :
- case :
- case :
- ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
- bgImage.color = tempColor;
- msgText.text = "阶段 x";
- break;
- }
- }
- public void UpdateUI(int s = ,int l = )
- {
- score += s;
- length += l;
- scoreText.text ="得分:\n"+score;
- lengthText.text = "长度\n" + length;
- }
- public void Pause()
- {
- isPause = !isPause;
- if(isPause)
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- else
- {
- Time.timeScale = ;
- pauseImage.sprite = pauseSprites[];
- }
- }
- }
MainUIController.cs
- using System.Collections;
- using System.Collections.Generic;
- 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;
- private void Awake()
- {
- lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",) + ",分数" + PlayerPrefs.GetInt("lasts",);
- bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", ) + ",分数" + PlayerPrefs.GetInt("bests",);
- }
- private 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", ) == )
- {
- border.isOn = true;
- PlayerPrefs.SetInt("border",);
- }
- else
- {
- noborder.isOn = true;
- PlayerPrefs.SetInt("border", );
- }
- }
- 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",);
- }
- }
- public void NoBorderSelected(bool isOn)
- {
- if (isOn)
- {
- //自由模式
- PlayerPrefs.SetInt("border", );
- }
- }
- public void StartGame()
- {
- UnityEngine.SceneManagement.SceneManager.LoadScene();
- }
- }
StartUIController.cs
Unity3D_(游戏)贪吃蛇的更多相关文章
- Java小游戏贪吃蛇
package snake; import java.awt.BorderLayout;import java.awt.Canvas;import java.awt.Color;import java ...
- 用Canvas制作小游戏——贪吃蛇
今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ...
- 第一个windows 小游戏 贪吃蛇
最近用dx尝试做了一个小的贪吃蛇游戏,代码放到github上面:https://github.com/nightwolf-chen/MyFreakout 说一下自己实现的过程: 首先,我把蛇这个抽象成 ...
- Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目
<贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...
- 使用JavaScript实现简单的小游戏-贪吃蛇
最近初学JavaScript,在这里分享贪吃蛇小游戏的实现过程, 希望能看到的前辈们能指出这个程序的不足之处. 大致思路 首先要解决的问题 随着蛇头的前进,尾巴也要前进. 用键盘控制蛇的运动方向. 初 ...
- Unity 3D游戏-贪吃蛇类游戏源码:重要方法和功能的实现
贪吃蛇类游戏源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 头部移动方式 2 生成 Shit 道具 ...
- JavaScript面向对象编程小游戏---贪吃蛇
1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. 2 这个demo是采用了 ...
- 最简单的HTML5游戏——贪吃蛇
<html> <head> <meta charset="UTF-8"/> <title>贪吃蛇</title> < ...
- c++小游戏——贪吃蛇
#include #include #include #include #include <conio.h> #include #include <windows.h> usi ...
随机推荐
- 使用Python基于OpenCV和Tesseract的OCR
OCR OCR(Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗.亮的模式确定其形状,然后用字符识别方法将形 ...
- Springboot实现上传文件接口,使用python的requests进行组装报文上传文件的方法
记录瞬间 近段时间使用Springboot实现了文件的上传服务,但是在使用python的requests进行post上传时,总是报错. 比如: 1.Current request is not a m ...
- Redis5版本集群搭建
一.简介 1.1 Redis是什么 Redis是一个开源的,使用ANSI C 编写,高性能的Key-Value的NoSQL数据库. 1.2 Redis特点 (1)基于内存 (2)可持久化数据 (3)具 ...
- redis 学习(13)-- BitMap
BitMap 什么是 BitMap BitMap,即位图,其实也就是 byte 数组,用二进制表示,只有 0 和 1 两个数字. 如图所示: 重要 API 命令 含义 getbit key offse ...
- jsp页面中使用 splitfn:split注意事项
我们有一个 字段存储内容是 xxxx意见~~@~~是 在页面上需要分开显示,格式为 xxx意见 是 使用 ${fn:split(comments, '~~@~~')[1]} 来分割是发现出现@符文字 ...
- luogu P3620 [APIO/CTSC 2007]数据备份
luogu 首先如果一条线不是了连接的相邻两个位置一定不优,把它拆成若干连接相邻位置的线.所以现在问题是有\(n\)个物品,选\(k\)个,要求选的位置不能相邻,求最小总和 如果没有选的位置不能相邻这 ...
- nginx(五)- linux下安装nginx与配置
linux系统为Centos 64位 准备目录 [root@instance-3lm099to ~]# mkdir /usr/local/nginx [root@instance-3lm099to ~ ...
- Linux下nouveau操作和GPU的操作,nouveau拯救
之前也提到了,旧机器上有一块NVIDIA的显卡,装了ubuntu16.04后一直没有安装驱动.这周算是有点时间,就差点作了死. 首先必须澄清,这个不是正确的安装过程,起码我就报了memory erro ...
- scala下划线的作用
https://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala Existent ...
- php 多肽实例
多态定义:只关心一个接口或者基类,而不关心一个对象的具体类.(同一类型,不同结果) 这里两个例子: 第一个,我们发现,基类定义了标准,子类进行了自我规则的实现.这是多态的一个要求.同时,这是满足重写: ...