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