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对象完全一样。
(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 = 0;y = step; } if (Input.GetKey(KeyCode.S)) { x = 0;y = -step; } if (Input.GetKey(KeyCode.A)) { x = -step;y = 0; } if (Input.GetKey(KeyCode.D)) { x = step;y = 0; } }
初始时及改变方向时不断让小蛇向着一个方向移动
private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = step;y = 0; }
Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("Test", 5); 它的意思是:5 秒之后调用 Test() 方法; 使用 Invoke() 方法需要注意 3点: 1 :它应该在 脚本的生命周期里的(Start、Update、OnGUI、FixedUpdate、LateUpdate)中被调用; 2:Invoke(); 不能接受含有参数的方法; 3:在 Time.ScaleTime = 0; 时, Invoke() 无效,因为它不会被调用到 Invoke() 也支持重复调用:InvokeRepeating("Test", 2 , 3); 这个方法的意思是指:2 秒后调用 Test() 方法,并且之后每隔 3 秒调用一次 Test() 方法 还有两个重要的方法: IsInvoking:用来判断某方法是否被延时,即将执行 CancelInvoke:取消该脚本上的所有延时方法
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",0,velocity); x = step;y = 0; } private void Update() { if (Input.GetKey(KeyCode.W)) { x = 0;y = step; } if (Input.GetKey(KeyCode.S)) { x = 0;y = -step; } if (Input.GetKey(KeyCode.A)) { x = -step;y = 0; } if (Input.GetKey(KeyCode.D)) { x = step;y = 0; } } 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)) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0); x = 0;y = step; } if (Input.GetKey(KeyCode.S)) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180); x = 0;y = -step; } if (Input.GetKey(KeyCode.A)) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90); x = -step;y = 0; } if (Input.GetKey(KeyCode.D)) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, -90); x = step;y = 0; } }
发现小球向左走时还能向右走,向下走时还能向上走
判断按键方法时候可以对方向进行一个判断
private void Update() { 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; } }
添加按下空格加快贪吃蛇向前移动速度
if (Input.GetKeyDown(KeyCode.Space)) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.2f); } if (Input.GetKeyUp(KeyCode.Space)) { CancelInvoke(); InvokeRepeating("Move", 0, 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",0,velocity); x = 0;y = step; } private 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); } }
第一个食物的随机生成
对游戏边界范围的判定
上边界与下边界
经测试
小蛇走11步碰到上边界,走10步碰到下边界
小蛇走19步碰到右边界,走11步碰到左边界
将食物和小蛇设置为预制体
创建一个GameObject空物体对象挂在脚本和预制体
游戏初始时获得游戏物体,并且生成食物
private void Start() { foodHolder = GameObject.Find("FoodHolder").transform; MakeFood(); }
随机生成食物的位置
public int xlimit = 18; public int ylimit = 10; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 11; void MakeFood() { //生成x和y的随机值 int x = Random.Range(-xlimit + xoffset,xlimit); int y = Random.Range(-ylimit,ylimit); //通过小蛇自身的步数长度来计算食物的活动空间 food.transform.localPosition = new Vector3(x * 20, y * 20, 0); }
随机生成食物的种类和位置
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 * 25, y * 25, 0); }
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class FoodMaker : MonoBehaviour { public int xlimit = 18; public int ylimit = 10; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 11; public GameObject foodPrefab; public Sprite[] foodSprites; private Transform foodHolder; private void Start() { foodHolder = GameObject.Find("FoodHolder").transform; MakeFood(); } 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 * 25, y * 25, 0); } }
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",0,velocity); x = 0;y = step; } private 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); } }
吃掉食物(销毁)以及食物的随机生成
给蛇头添加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 = 17; public int ylimit = 8; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 11; 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(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 * 25, y * 25, 0); } }
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",0,velocity); x = 0;y = step; } private 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); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Food")) { Destroy(collision.gameObject); FoodMaker.Instance.MakeFood(); } } }
蛇身吃掉食物的变长
添加一个Image放置蛇身图片,添加Box Collider 2D碰撞器(碰撞器的范围不用太大,以免对食物产生不可描述的误操作)
SnakeHead.cs脚本中生成蛇身
创建一个集合,用来保存蛇身部分(两张图片不断轮流交换)
public List<RectTransform> bodyList = new List<RectTransform>(); public GameObject bodyPrefab; public Sprite[] bodySprites = new Sprite[2];
生成蛇身体方法
void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; 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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; }
Unity中将预制体与贪吃蛇头部绑定一下
蛇碰到食物后开始生成蛇身
void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //food.transform.localPosition = new Vector3( x, y, 0); } }
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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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(); } } }
游戏的自由模式
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到下边界时再往上走一步后从上边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
switch(collision.gameObject.name) { case "Up": transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+20,transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x+140,transform.localPosition.y , transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x+170, 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } }
当蛇吃到食物后,有百分之20的机率生成道具
if (collision.gameObject.CompareTag("Food")) { Destroy(collision.gameObject); Grow(); if (Random.Range(0,100)<20) { 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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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(0,100)<20) { 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+20,transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x+140,transform.localPosition.y , transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x+170, transform.localPosition.y, transform.localPosition.z); break; } } } }
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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } } }
分数与长度与游戏背景切换
新建一个脚本MainUIController.cs来存储蛇的分数与长度
分数的单例模式
//单例模式 private static MainUIController _instance; public static MainUIController Instance { get { return _instance; } }
游戏加分方法 默认吃到一个食物加5分1个长度 获得道具加分会更高
public void UpdateUI(int s = 5,int l = 1) { 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(0,100)<20) { FoodMaker.Instance.MakeFood(true); } else { FoodMaker.Instance.MakeFood(false); } } else if(collision.gameObject.CompareTag("Reward")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(Random.Range(5,15)*10); Grow(); }
当分数达到一定数值时能进行游戏背景变色
private void Update() { switch (score / 100) { case 3: ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor); bgImage.color=tempColor; msgText.text = "阶段" + 2; break; case 5: ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 3; break; case 7: ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 4; break; case 9: ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 5; break; case 11: 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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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(0,100)<20) { FoodMaker.Instance.MakeFood(true); } else { FoodMaker.Instance.MakeFood(false); } } else if(collision.gameObject.CompareTag("Reward")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(Random.Range(5,15)*10); 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+20,transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x+140,transform.localPosition.y , transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x+170, transform.localPosition.y, transform.localPosition.z); break; } } } }
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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } } }
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 = 0; public int length = 0; public Text msgText; public Text scoreText; public Text lengthText; public Image bgImage; private Color tempColor; void Awake() { _instance = this; } private void Update() { switch (score / 100) { case 3: ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor); bgImage.color=tempColor; msgText.text = "阶段" + 2; break; case 5: ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 3; break; case 7: ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 4; break; case 9: ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 5; break; case 11: ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段 x"; break; } } public void UpdateUI(int s = 5,int l = 1) { score += s; length += l; scoreText.text ="得分:\n"+score; lengthText.text = "长度\n" + length; } }
暂停与返回按钮
对按钮进行引用以及添加一个图片Sprite[]
public Button pauseButton; public Sprite[] pauseSprites;
设置一个变量记录游戏状态
private bool isPause = false ;
点击按钮时候对游戏状态取反
public void Pause() { isPause = !isPause; if(isPause) { Time.timeScale = 0; pauseButton.GetComponent<Image>().sprite = pauseSprites[1]; } else { Time.timeScale = 1; pauseButton.GetComponent<Image>().sprite = pauseSprites[0]; } }
Time.timeScale 传送门
Script中对图片、按钮进行绑定
在onclick()
解决按键冲突
按键控制器Edit->Project Settings-> Input
private void Update() { if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false) { CancelInvoke(); InvokeRepeating("Move", 0, velocity); } if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0); x = 0;y = step; } if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180); x = 0;y = -step; } if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90); x = -step;y = 0; } if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, -90); x = step;y = 0; } }
接下来实现返回按钮
public void Home() { UnityEngine.SceneManagement.SceneManager.LoadScene(0); }
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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false) { CancelInvoke(); InvokeRepeating("Move", 0, velocity); } if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0); x = 0;y = step; } if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180); x = 0;y = -step; } if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90); x = -step;y = 0; } if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false) { 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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(0,100)<20) { FoodMaker.Instance.MakeFood(true); } else { FoodMaker.Instance.MakeFood(false); } } else if(collision.gameObject.CompareTag("Reward")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(Random.Range(5,15)*10); 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+20,transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x+140,transform.localPosition.y , transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x+170, transform.localPosition.y, transform.localPosition.z); break; } } } }
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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } } public void Home() { UnityEngine.SceneManagement.SceneManager.LoadScene(0); } }
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 = 0; public int length = 0; 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 / 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("#CCEEFFFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 3; break; case 7: case 8: ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 4; break; case 9: case 10: ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 5; break; case 11: case 12: case 13: ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段 x"; 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]; } } }
游戏贪吃蛇死亡处理
添加游戏死亡标记
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(1); }
游戏结束时候记录最高得分
void Die() { CancelInvoke(); isDie = true; Instantiate(dieEffect); //记录游戏的最后长度 PlayerPrefs.SetInt("last1",MainUIController.Instance.length); PlayerPrefs.SetInt("lasts", MainUIController.Instance.score); //当游戏长度大于最高得分时 if (PlayerPrefs.GetInt("bests", 0)<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);
用户设置的存储
添加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[0] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh01", "sh0201")); bodySprites[1] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh02", "sh0202")); }
判断游戏模式
添加一个模式表示位
public bool hasBorder = true;
游戏初始时默认无边界
void Start() { if (PlayerPrefs.GetInt("border", 1)==0) { 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 + 20, transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x + 140, transform.localPosition.y, transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x + 170, 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",0) + ",分数" + PlayerPrefs.GetInt("lasts",0); bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", 0) + ",分数" + PlayerPrefs.GetInt("bests",0); } 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); } } public void StartGame() { UnityEngine.SceneManagement.SceneManager.LoadScene(1); } }
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 = 0; public int length = 0; 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", 1)==0) { hasBorder = false; //取消边界上的颜色 foreach(Transform t in bgImage.gameObject.transform) { t.gameObject.GetComponent<Image>().enabled = false; } } } private 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("#CCEEFFFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 3; break; case 7: case 8: ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 4; break; case 9: case 10: ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 5; break; case 11: case 12: case 13: ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段 x"; 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]; } } }
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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } } public void Home() { UnityEngine.SceneManagement.SceneManager.LoadScene(0); } }
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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; //通过Resources.Load(string path)方法加载资源; gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02")); bodySprites[0] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201")); bodySprites[1] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202")); } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false) { CancelInvoke(); InvokeRepeating("Move", 0, velocity); } if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0); x = 0;y = step; } if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180); x = 0;y = -step; } if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90); x = -step;y = 0; } if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false) { 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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", 0)<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(1); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Food")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(); Grow(); if (Random.Range(0,100)<20) { FoodMaker.Instance.MakeFood(true); } else { FoodMaker.Instance.MakeFood(false); } } else if(collision.gameObject.CompareTag("Reward")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(Random.Range(5,15)*10); 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 + 20, transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x + 140, transform.localPosition.y, transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x + 170, transform.localPosition.y, transform.localPosition.z); break; } } } } }
添加游戏音乐
Main场景摄像机上绑定一个Audio Source音乐播放器
吃到东西和游戏结束时分别播放两个不同的音乐
public AudioClip eatClip; public AudioClip dieClip;
void Grow() { //播放贪吃蛇变长音乐 AudioSource.PlayClipAtPoint(eatClip,Vector3.zero); int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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", 0)<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[2]; private void Awake() { canvas = GameObject.Find("Canvas").transform; //通过Resources.Load(string path)方法加载资源; gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02")); bodySprites[0] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201")); bodySprites[1] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202")); } private void Start() { //重复调用 InvokeRepeating("Move",0,velocity); x = 0;y = step; } private void Update() { if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false) { CancelInvoke(); InvokeRepeating("Move",0,velocity - 0.3f); } if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false) { CancelInvoke(); InvokeRepeating("Move", 0, velocity); } if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 0); x = 0;y = step; } if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 180); x = 0;y = -step; } if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false) { gameObject.transform.localRotation = Quaternion.Euler(0, 0, 90); x = -step;y = 0; } if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false) { 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); if (bodyList.Count > 0) { //由于是双色蛇身,此方法弃用 //将蛇尾移动到蛇头移动前的位置 // bodyList.Last().localPosition = headPos; //将蛇尾在List中的位置跟新到最前 // bodyList.Insert(0, bodyList.Last()); //溢出List最末尾的蛇尾引用 // bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身 for(int i =bodyList.Count-2;i>=0 ;i--) { //每一个蛇身都移动到它前面一个 bodyList[i + 1].localPosition = bodyList[i].localPosition; } //第一个蛇身移动到蛇头移动前的位置 bodyList[0].localPosition = headPos; } } void Grow() { //播放贪吃蛇变长音乐 AudioSource.PlayClipAtPoint(eatClip,Vector3.zero); int index = (bodyList.Count % 2 == 0) ? 0 : 1; GameObject body = Instantiate(bodyPrefab,new Vector3(200000,2000000,0),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", 0)<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(1); } private void OnTriggerEnter2D(Collider2D collision) { if (collision.gameObject.CompareTag("Food")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(); Grow(); if (Random.Range(0,100)<20) { FoodMaker.Instance.MakeFood(true); } else { FoodMaker.Instance.MakeFood(false); } } else if(collision.gameObject.CompareTag("Reward")) { Destroy(collision.gameObject); MainUIController.Instance.UpdateUI(Random.Range(5,15)*10); 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 + 20, transform.localPosition.z); break; case "Down": transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - 20, transform.localPosition.z); break; case "Left": transform.localPosition = new Vector3(-transform.localPosition.x + 140, transform.localPosition.y, transform.localPosition.z); break; case "Right": transform.localPosition = new Vector3(-transform.localPosition.x + 170, transform.localPosition.y, transform.localPosition.z); break; } } } } }
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 = 18; public int ylimit = 9; //x轴活动空间不对称问题,对x轴的偏移值 public int xoffset = 10; 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(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 * 20, y * 20, 0); //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 * 20, y * 20, 0); } } public void Home() { UnityEngine.SceneManagement.SceneManager.LoadScene(0); } }
场景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 = 0; public int length = 0; 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", 1)==0) { hasBorder = false; //取消边界上的颜色 foreach(Transform t in bgImage.gameObject.transform) { t.gameObject.GetComponent<Image>().enabled = false; } } } private 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("#CCEEFFFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 3; break; case 7: case 8: ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 4; break; case 9: case 10: ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段" + 5; break; case 11: case 12: case 13: ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor); bgImage.color = tempColor; msgText.text = "阶段 x"; 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]; } } }
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",0) + ",分数" + PlayerPrefs.GetInt("lasts",0); bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", 0) + ",分数" + PlayerPrefs.GetInt("bests",0); } 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); } } public void StartGame() { UnityEngine.SceneManagement.SceneManager.LoadScene(1); } }