Unity3D_(游戏)贪吃蛇
Unity制作贪吃蛇小游戏
玩家通过“WASD”控制小蛇上下左右移动,蛇头撞倒食物,则食物被吃掉,蛇身体长一节,接着又出现食物,等待蛇来吃,如果蛇在移动中撞到墙或身体交叉蛇头撞倒自己身体游戏结束
可通过游戏开始前对小蛇皮肤进行选择
自由模式下蛇头可以穿过四周的墙
使用本地持久化保存与读取的类——PlayerPrefs类对玩家游戏数据的存储
PlayerPrefs类存储位置 传送门
Unity圣典 传送门
游戏项目已托管到Github上 传送门
游戏展示
对玩家的游戏数据记录
游戏界面存储玩家最高分以及上一次游戏的分数
游戏换肤
为玩家可以选择蓝色小蛇或黄色小蛇
游戏模式
边界模式下蛇撞到边界判定游戏结束
自由模式下蛇碰到边界时会从另一个边界线出来
(文字最下边有游戏脚本源代码)
实现过程
制作开始场景UI界面
添加一个Canvas作为游戏开始场景并将Canvas下的Render Mode设置为Screen Space—Camera
1:Screen Space-Overlay:这种模式层级视图中不需要任何的摄像机,且UI出现在所有摄像机的最前面。
2:Screen Space-Camera:这种模式需要绑定一个UICamrea,它支持UI前面显示3D对象和粒子系统。
3:World Space:这种模式,UI和3d对象完全一样。
Canvas 三种渲染模式如下
(2D游戏常用Screen Space-Camera模式,3D游戏常用Screen Space-Overlay模式)
Canvas Scaler(Script)个人比较喜欢设置UI Scale Mode设置成Scale With Screen Si 根据屏幕尺寸来调整UI的缩放值
指定渲染摄像机
添加游戏背景及控制面板
使用UGUI制作游戏场景界面
Bg(Image):制作游戏背景界面
ControlPanel(Panel):制作游戏选项区域
Title(Text):制作游戏标题
Go(Image):制作游戏开始图标
添加Button控件,制作成按钮
添加Outline外边框和Shadow阴影组件(逼真图片按钮)
Text:"开始"文本
添加十张Image作为游戏背景图片
食物作为游戏背景太鲜明时,可以把食物的透明度调为150
制作Text文字背景
Mode下添加一个Toggle提供玩家对模式的选择
(给文字添加Outline给玩家一种朦胧感)
边界模式下,蛇撞墙后判断游戏结束
复制边界模式Toggle,修改文字为自由模式(自由模式下蛇撞墙后不会判定结束游戏)
边界模式和自由模式玩家只能选择一个
给Mode添加Toggle Group组件
将Toggle Group组件绑定给Border和NoBorder
is on :当前标签是否勾选
同理添加小蛇皮肤属性
将选择小蛇皮肤也设置成Toggle Group
"黄色小蛇"和"自由模式" is on 去掉勾选
游戏场景UI界面
ControlPanel下的按钮、文本控件
Msg(Text):玩家选择游戏模式
Score(Text):玩家当前得分
Length(Text):当前蛇自身长度
Home(Image):返回主页面按钮
Pause(Image):停止游戏按钮
给游戏场景添加边界
Bg下创建两个GameObject,设置(锚点)GameObject范围,添加Box Collider 2D作为游戏碰撞器
给小蛇添加活动范围,添加一个Box Collider 2D碰撞器
为了将活动范围标记出来,可以给碰撞其添加一个Image红色图片作为围墙
修改一下碰撞器范围
制作贪吃蛇舌头并让其移动
添加Image制作舌头,设置好舌头大小
创建SnakeHead.cs脚本并绑定到蛇头部
控制小蛇头部移动脚本
void Move()
{
headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
}
添加键盘按钮事件
private void Update()
{
if (Input.GetKey(KeyCode.W))
{
x = ;y = step;
}
if (Input.GetKey(KeyCode.S))
{
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A))
{
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D))
{
x = step;y = ;
}
}
初始时及改变方向时不断让小蛇向着一个方向移动
private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = step;y = ;
}
Invoke() 方法是 Unity3D 的一种委托机制 如: Invoke("Test", ); 它的意思是: 秒之后调用 Test() 方法; 使用 Invoke() 方法需要注意 3点: :它应该在 脚本的生命周期里的(Start、Update、OnGUI、FixedUpdate、LateUpdate)中被调用; :Invoke(); 不能接受含有参数的方法; :在 Time.ScaleTime = ; 时, Invoke() 无效,因为它不会被调用到 Invoke() 也支持重复调用:InvokeRepeating("Test", , ); 这个方法的意思是指: 秒后调用 Test() 方法,并且之后每隔 秒调用一次 Test() 方法 还有两个重要的方法: IsInvoking:用来判断某方法是否被延时,即将执行
CancelInvoke:取消该脚本上的所有延时方法
Unity中Invoke 和 InvokeRepeating的区别
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class SnakeHead : MonoBehaviour { public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos; private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = step;y = ;
} private void Update()
{
if (Input.GetKey(KeyCode.W))
{
x = ;y = step;
}
if (Input.GetKey(KeyCode.S))
{
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A))
{
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D))
{
x = step;y = ;
}
} void Move()
{
headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
}
}
SnakeHead.cs
给小蛇头部添加转动时改变头部方向动画
private void Update()
{
if (Input.GetKey(KeyCode.W))
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S))
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A))
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D))
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
}
发现小球向左走时还能向右走,向下走时还能向上走
判断按键方法时候可以对方向进行一个判断
private void Update()
{
if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
}
添加按下空格加快贪吃蛇向前移动速度
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.2f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
}
Unity圣典 传送门
MonoBehaviour.CancelInvoke 取消调用
MonoBehaviour.InvokeRepeating 重复调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class SnakeHead : MonoBehaviour { public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos; private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.2f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
}
}
SnakeHead.cs
第一个食物的随机生成
对游戏边界范围的判定
上边界与下边界
经测试
小蛇走11步碰到上边界,走10步碰到下边界
小蛇走19步碰到右边界,走11步碰到左边界
将食物和小蛇设置为预制体
创建一个GameObject空物体对象挂在脚本和预制体
游戏初始时获得游戏物体,并且生成食物
private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood();
}
随机生成食物的位置
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ; void MakeFood()
{
//生成x和y的随机值
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
//通过小蛇自身的步数长度来计算食物的活动空间
food.transform.localPosition = new Vector3(x * , y * , );
}
随机生成食物的种类和位置
void MakeFood()
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
//通过小蛇自身的步数长度来计算食物的活动空间
food.transform.localPosition = new Vector3(x * , y * , );
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood();
} void MakeFood()
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
//通过小蛇自身的步数长度来计算食物的活动空间
food.transform.localPosition = new Vector3(x * , y * , );
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class SnakeHead : MonoBehaviour { public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos; private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.2f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
}
}
SnakeHead.cs
吃掉食物(销毁)以及食物的随机生成
给蛇头添加Box Collider 2D碰撞器,为避免蛇头未碰撞食物时碰撞器就碰撞到食物,可以设置碰撞器范围比蛇头小一圈
勾选Is Trigger,当物体碰到食物及边界时,可以进入边界再判定游戏结束
给蛇头添加Rigidbody 2D碰撞器,设置重力 Gravity Scale为0 (不然蛇头在开始游戏时就会不断往下掉)
同理,给食物预设体Food添加Box Collider 2D碰撞器
新创建一个Food标签作为标记
将Food预设体标签设置为Food
SnakeHead.cs中添加食物碰撞生成新食物方法
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
FoodMaker.Instance.MakeFood();
}
}
FoodMaker.cs
添加一个单例模式
//单例模式
private static FoodMaker _instance;
//可以通过外部去调用方法修改_instance的值
public static FoodMaker Instance
{
get
{
return _instance;
}
} //初始化
private void Awake()
{
_instance = this;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood();
} public void MakeFood()
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
//通过小蛇自身的步数长度来计算食物的活动空间
food.transform.localPosition = new Vector3(x * , y * , );
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine; public class SnakeHead : MonoBehaviour { public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos; private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.2f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
headPos = gameObject.transform.localPosition;
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
FoodMaker.Instance.MakeFood();
}
} }
SnakeHead.cs
蛇身吃掉食物的变长
添加一个Image放置蛇身图片,添加Box Collider 2D碰撞器(碰撞器的范围不用太大,以免对食物产生不可描述的误操作)
SnakeHead.cs脚本中生成蛇身
创建一个集合,用来保存蛇身部分(两张图片不断轮流交换)
public List<RectTransform> bodyList = new List<RectTransform>(); public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[];
生成蛇身体方法
void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas,false);
bodyList.Add(body.transform);
}
蛇生体移动的方法
创建一个链表,当蛇吃了食物后,将蛇身放置到链表中
public List<Transform> bodyList = new List<Transform>();
将图片放置到bodySprites中(两张),存放的都是bodyPrefab
public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
}
Unity中将预制体与贪吃蛇头部绑定一下
蛇碰到食物后开始生成蛇身
void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
Grow();
FoodMaker.Instance.MakeFood();
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood();
} public void MakeFood()
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas; public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
Grow();
FoodMaker.Instance.MakeFood();
}
} }
SnakeHead.cs
游戏的自由模式
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到下边界时再往上走一步后从上边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
当小蛇撞到上边界时再往下走一步后从下边界出现
switch(collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
break;
}
奖励目标的生成
添加一个Reward(Image)作为奖励目标背景图片
调整奖励背景图片和食物大小保持一样,并添加Box Collider 2D组件
将Resward作为预制体
FoodMaker.cs上绑定rewardPrefabs预制体
public GameObject rewardPrefab;
判断是否生成道具
public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
}
当蛇吃到食物后,有百分之20的机率生成道具
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
当蛇吃到道具时,道具销毁
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
Grow();
}
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas; public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
Grow();
}
else if(collision.gameObject.CompareTag("Body"))
{
Debug.Log("Die");
}
else
{
switch(collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
break;
}
}
} }
SnakeHead.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
} public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
}
}
FoodMaker.cs
分数与长度与游戏背景切换
新建一个脚本MainUIController.cs来存储蛇的分数与长度
分数的单例模式
//单例模式
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
}
游戏加分方法 默认吃到一个食物加5分1个长度 获得道具加分会更高
public void UpdateUI(int s = ,int l = )
{
score += s;
length += l;
scoreText.text ="得分:\n"+score;
lengthText.text = "长度\n" + length;
}
当蛇吃到食物或道具时调用UpdateUI()方法
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI(Random.Range(,)*);
Grow();
}
当分数达到一定数值时能进行游戏背景变色
private void Update()
{
switch (score / )
{
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
bgImage.color=tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段 x";
break;
}
}
将脚本放在Script游戏物体上,并绑定分数版、背景等
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas; public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space))
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step )
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI(Random.Range(,)*);
Grow();
}
else if(collision.gameObject.CompareTag("Body"))
{
Debug.Log("Die");
}
else
{
switch(collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
break;
}
}
} }
SnakeHead.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
} public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class MainUIController : MonoBehaviour { //单例模式
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
} public int score = ;
public int length = ;
public Text msgText;
public Text scoreText;
public Text lengthText;
public Image bgImage;
private Color tempColor; void Awake()
{
_instance = this;
} private void Update()
{
switch (score / )
{
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
bgImage.color=tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段 x";
break;
}
} public void UpdateUI(int s = ,int l = )
{
score += s;
length += l;
scoreText.text ="得分:\n"+score;
lengthText.text = "长度\n" + length;
} }
MainUIController.cs
暂停与返回按钮
对按钮进行引用以及添加一个图片Sprite[]
public Button pauseButton;
public Sprite[] pauseSprites;
设置一个变量记录游戏状态
private bool isPause = false ;
点击按钮时候对游戏状态取反
public void Pause()
{
isPause = !isPause;
if(isPause)
{
Time.timeScale = ;
pauseButton.GetComponent<Image>().sprite = pauseSprites[];
}
else
{
Time.timeScale = ;
pauseButton.GetComponent<Image>().sprite = pauseSprites[];
}
}
Time.timeScale 传送门
Script中对图片、按钮进行绑定
在onclick()
解决按键冲突
按键控制器Edit->Project Settings-> Input
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false)
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false)
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
}
Update()中对键盘按下事件进行处理
接下来实现返回按钮
public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
Home按钮上添加点击事件
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas; public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false)
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false)
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI(Random.Range(,)*);
Grow();
}
else if(collision.gameObject.CompareTag("Body"))
{
Debug.Log("Die");
}
else
{
switch(collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x,-transform.localPosition.y+,transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y-, transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x+,transform.localPosition.y , transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x+, transform.localPosition.y, transform.localPosition.z);
break;
}
}
} }
SnakeHead.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
} public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
} public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class MainUIController : MonoBehaviour { //单例模式
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
} public int score = ;
public int length = ;
public Text msgText;
public Text scoreText;
public Text lengthText;
public Image bgImage;
private Color tempColor; public Image pauseImage;
public Sprite[] pauseSprites;
public bool isPause = false ; void Awake()
{
_instance = this;
} private void Update()
{
switch (score / )
{
case :
case :
case :
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
bgImage.color=tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
case :
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段 x";
break;
}
} public void UpdateUI(int s = ,int l = )
{
score += s;
length += l;
scoreText.text ="得分:\n"+score;
lengthText.text = "长度\n" + length;
} public void Pause()
{
isPause = !isPause;
if(isPause)
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
else
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
}
}
MainUIController.cs
游戏贪吃蛇死亡处理
添加游戏死亡标记
private bool isDie = false;
判断游戏死亡时触发的粒子特效
void Die()
{
CancelInvoke();
isDie = true;
Instantiate(dieEffect);
StartCoroutine(GameOver(1.0f));
}
通过Unity协成进行游戏的重新开始
IEnumerator GameOver(float t)
{
yield return new WaitForSeconds(t);
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
游戏结束时候记录最高得分
void Die()
{
CancelInvoke();
isDie = true;
Instantiate(dieEffect);
//记录游戏的最后长度
PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
//当游戏长度大于最高得分时
if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
{
//将当前游戏长度和分数记录到best1和bests当中
PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
}
StartCoroutine(GameOver(1.0f));
}
1、存储值://本地化存储方式,一般用在保存玩家的偏好设置中,常见于玩家设置,游戏分数存取………… PlayerPrefs.SetFloat(string key,float value); //通过key 与value 存储,就像键值对一样。 PlayerPrefs.SetInt(string key,Int value); PlayerPrefs.SetString(string key,string value); 2、读取值: PlayerPrefs.GetFloat(string key); //通过key得到存储的value值 PlayerPrefs.GetInt(string key); PlayerPrefs.GetString(string key);
Unity 中PlayerPrefs类实现数据本地化存储
用户设置的存储
添加StartUIController.cs脚本控制Gary开始场景界面
获得Gary开始场景界面Text文本控件
public Text lastText;
public Text bestText;
对文本控件的值进行读取刷新
private void Awake()
{
lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",0) + ",分数" + PlayerPrefs.GetInt("lasts",0);
lastText.text = "最好:长度" + PlayerPrefs.GetInt("best1", 0) + ",分数" + PlayerPrefs.GetInt("bests", 0);
}
Gary场景中创建一个空物体游戏对象ScriptHolder挂在游戏脚本
实现点击开始进入场景功能
切换场景方法
public void StartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene(1);
}
Gary场景中Start添加onClick()点击事件
(可以看到此时已经实现上次分数以及最高分数的存储)
动态绑定选择游戏皮肤、模式
存储玩家的选择
private void Start()
{
if (PlayerPrefs.GetString("sh", "sh01") == "sh01")
{
blue.isOn = true;
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
else
{
yellow.isOn = true;
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
if (PlayerPrefs.GetInt("border", 1) == 1)
{
border.isOn = true;
PlayerPrefs.SetInt("border",1);
}
else
{
noborder.isOn = true;
PlayerPrefs.SetInt("border", 0);
}
} public void BlueSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
} public void YellowSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
} public void BorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border",1);
}
} public void NoBorderSelected(bool isOn)
{
if (isOn)
{
//自由模式
PlayerPrefs.SetInt("border", 0);
}
}
完成换肤与数据读取
使用泛型加载游戏换肤方法
private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
//通过Resources.Load(string path)方法加载资源;
gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh01", "sh0201"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sh02", "sh0202"));
}
判断游戏模式
添加一个模式表示位
public bool hasBorder = true;
游戏初始时默认无边界
void Start()
{
if (PlayerPrefs.GetInt("border", )==)
{
hasBorder = false;
//取消边界上的颜色
foreach(Transform t in bgImage.gameObject.transform)
{
t.gameObject.GetComponent<Image>().enabled = false;
}
}
}
SnakeHead.cs脚本中对游戏碰到边界死亡进行判定
if (MainUIController.Instance.hasBorder)
{
Die();
}
else
{
switch (collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class StartUIController : MonoBehaviour { public Text lastText;
public Text bestText;
public Toggle blue;
public Toggle yellow;
public Toggle border;
public Toggle noborder; private void Awake()
{
lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",) + ",分数" + PlayerPrefs.GetInt("lasts",);
bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", ) + ",分数" + PlayerPrefs.GetInt("bests",);
} private void Start()
{
if (PlayerPrefs.GetString("sh", "sh01") == "sh01")
{
blue.isOn = true;
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
else
{
yellow.isOn = true;
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
if (PlayerPrefs.GetInt("border", ) == )
{
border.isOn = true;
PlayerPrefs.SetInt("border",);
}
else
{
noborder.isOn = true;
PlayerPrefs.SetInt("border", );
}
} public void BlueSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
} public void YellowSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
} public void BorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border",);
}
} public void NoBorderSelected(bool isOn)
{
if (isOn)
{
//自由模式
PlayerPrefs.SetInt("border", );
}
} public void StartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
}
StartUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class MainUIController : MonoBehaviour { //单例模式
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
} public int score = ;
public int length = ;
public Text msgText;
public Text scoreText;
public Text lengthText;
public Image bgImage;
private Color tempColor; public Image pauseImage;
public Sprite[] pauseSprites;
public bool isPause = false ;
public bool hasBorder = true; void Awake()
{
_instance = this;
} void Start()
{
if (PlayerPrefs.GetInt("border", )==)
{
hasBorder = false;
//取消边界上的颜色
foreach(Transform t in bgImage.gameObject.transform)
{
t.gameObject.GetComponent<Image>().enabled = false;
}
}
} private void Update()
{
switch (score / )
{
case :
case :
case :
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
bgImage.color=tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
case :
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段 x";
break;
}
} public void UpdateUI(int s = ,int l = )
{
score += s;
length += l;
scoreText.text ="得分:\n"+score;
lengthText.text = "长度\n" + length;
} public void Pause()
{
isPause = !isPause;
if(isPause)
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
else
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
}
}
MainUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
} public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
} public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
}
FoodMaker.cs
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas;
private bool isDie = false; public GameObject dieEffect;
public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
//通过Resources.Load(string path)方法加载资源;
gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202"));
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false)
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false)
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} void Die()
{
CancelInvoke();
isDie = true;
Instantiate(dieEffect);
//记录游戏的最后长度
PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
//当游戏长度大于最高得分时
if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
{
//将当前游戏长度和分数记录到best1和bests当中
PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
}
StartCoroutine(GameOver(1.0f));
} IEnumerator GameOver(float t)
{
yield return new WaitForSeconds(t);
UnityEngine.SceneManagement.SceneManager.LoadScene();
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI(Random.Range(,)*);
Grow();
}
else if(collision.gameObject.CompareTag("Body"))
{
Die();
}
else
{
if (MainUIController.Instance.hasBorder)
{
Die();
}
else
{
switch (collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
}
}
}
} }
SnakeHead.cs
添加游戏音乐
Main场景摄像机上绑定一个Audio Source音乐播放器
吃到东西和游戏结束时分别播放两个不同的音乐
public AudioClip eatClip;
public AudioClip dieClip;
void Grow()
{
//播放贪吃蛇变长音乐
AudioSource.PlayClipAtPoint(eatClip,Vector3.zero);
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} void Die()
{
//播放死亡音乐
AudioSource.PlayClipAtPoint(dieClip, Vector3.zero);
CancelInvoke();
isDie = true;
Instantiate(dieEffect);
//记录游戏的最后长度
PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
//当游戏长度大于最高得分时
if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
{
//将当前游戏长度和分数记录到best1和bests当中
PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
}
StartCoroutine(GameOver(1.0f));
}
游戏源代码
控制蛇和食物脚本
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI; public class SnakeHead : MonoBehaviour { public List<Transform> bodyList = new List<Transform>();
public float velocity=0.35f;
public int step;
private int x;
private int y;
private Vector3 headPos;
private Transform canvas;
private bool isDie = false; public AudioClip eatClip;
public AudioClip dieClip;
public GameObject dieEffect;
public GameObject bodyPrefab;
public Sprite[] bodySprites = new Sprite[]; private void Awake()
{
canvas = GameObject.Find("Canvas").transform;
//通过Resources.Load(string path)方法加载资源;
gameObject.GetComponent<Image>().sprite = Resources.Load<Sprite>(PlayerPrefs.GetString("sh", "sh02"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb01", "sb0201"));
bodySprites[] = Resources.Load<Sprite>(PlayerPrefs.GetString("sb02", "sb0202"));
} private void Start()
{
//重复调用
InvokeRepeating("Move",,velocity);
x = ;y = step;
} private void Update()
{
if (Input.GetKeyDown(KeyCode.Space)&&MainUIController.Instance.isPause==false&&isDie==false)
{
CancelInvoke();
InvokeRepeating("Move",,velocity - 0.3f);
} if (Input.GetKeyUp(KeyCode.Space) && MainUIController.Instance.isPause == false && isDie == false)
{
CancelInvoke();
InvokeRepeating("Move", , velocity);
} if (Input.GetKey(KeyCode.W) && y!=-step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = step;
}
if (Input.GetKey(KeyCode.S) && y!=step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = ;y = -step;
}
if (Input.GetKey(KeyCode.A) && x!=step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , );
x = -step;y = ;
}
if (Input.GetKey(KeyCode.D) && x!=-step && MainUIController.Instance.isPause == false && isDie == false)
{
gameObject.transform.localRotation = Quaternion.Euler(, , -);
x = step;y = ;
}
} void Move()
{
//保存下来蛇头移动前的位置
headPos = gameObject.transform.localPosition;
//蛇头向期望位置移动
gameObject.transform.localPosition = new Vector3(headPos.x+x,headPos.y+y,headPos.z);
if (bodyList.Count > )
{
//由于是双色蛇身,此方法弃用
//将蛇尾移动到蛇头移动前的位置
// bodyList.Last().localPosition = headPos;
//将蛇尾在List中的位置跟新到最前
// bodyList.Insert(0, bodyList.Last());
//溢出List最末尾的蛇尾引用
// bodyList.RemoveAt(bodyList.Count - 1); //从后面开始移动蛇身
for(int i =bodyList.Count-;i>= ;i--)
{
//每一个蛇身都移动到它前面一个
bodyList[i + ].localPosition = bodyList[i].localPosition;
}
//第一个蛇身移动到蛇头移动前的位置
bodyList[].localPosition = headPos; }
} void Grow()
{
//播放贪吃蛇变长音乐
AudioSource.PlayClipAtPoint(eatClip,Vector3.zero);
int index = (bodyList.Count % == ) ? : ;
GameObject body = Instantiate(bodyPrefab,new Vector3(,,),Quaternion.identity);
body.GetComponent<Image>().sprite = bodySprites[index];
body.transform.SetParent(canvas, false);
bodyList.Add(body.transform);
} void Die()
{
//播放死亡音乐
AudioSource.PlayClipAtPoint(dieClip, Vector3.zero);
CancelInvoke();
isDie = true;
Instantiate(dieEffect);
//记录游戏的最后长度
PlayerPrefs.SetInt("last1",MainUIController.Instance.length);
PlayerPrefs.SetInt("lasts", MainUIController.Instance.score);
//当游戏长度大于最高得分时
if (PlayerPrefs.GetInt("bests", )<MainUIController.Instance.score)
{
//将当前游戏长度和分数记录到best1和bests当中
PlayerPrefs.SetInt("best1", MainUIController.Instance.length);
PlayerPrefs.SetInt("bests", MainUIController.Instance.score);
}
StartCoroutine(GameOver(1.0f));
} IEnumerator GameOver(float t)
{
yield return new WaitForSeconds(t);
UnityEngine.SceneManagement.SceneManager.LoadScene();
} private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("Food"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI();
Grow();
if (Random.Range(,)<)
{
FoodMaker.Instance.MakeFood(true);
}
else
{
FoodMaker.Instance.MakeFood(false);
}
}
else if(collision.gameObject.CompareTag("Reward"))
{
Destroy(collision.gameObject);
MainUIController.Instance.UpdateUI(Random.Range(,)*);
Grow();
}
else if(collision.gameObject.CompareTag("Body"))
{
Die();
}
else
{
if (MainUIController.Instance.hasBorder)
{
Die();
}
else
{
switch (collision.gameObject.name)
{
case "Up":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y + , transform.localPosition.z);
break;
case "Down":
transform.localPosition = new Vector3(transform.localPosition.x, -transform.localPosition.y - , transform.localPosition.z);
break;
case "Left":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
case "Right":
transform.localPosition = new Vector3(-transform.localPosition.x + , transform.localPosition.y, transform.localPosition.z);
break;
}
}
}
} }
SnakeHead.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class FoodMaker : MonoBehaviour { //单例模式
private static FoodMaker _instance;
public static FoodMaker Instance
{
get
{
return _instance;
}
}
public int xlimit = ;
public int ylimit = ;
//x轴活动空间不对称问题,对x轴的偏移值
public int xoffset = ;
public GameObject foodPrefab;
public GameObject rewardPrefab;
public Sprite[] foodSprites;
private Transform foodHolder; private void Awake()
{
_instance = this;
} private void Start()
{
foodHolder = GameObject.Find("FoodHolder").transform;
MakeFood(false);
} public void MakeFood(bool isReward)
{
int index = Random.Range(,foodSprites.Length);
GameObject food = Instantiate(foodPrefab);
food.GetComponent<Image>().sprite = foodSprites[index];
food.transform.SetParent(foodHolder,false);
int x = Random.Range(-xlimit + xoffset,xlimit);
int y = Random.Range(-ylimit,ylimit);
food.transform.localPosition = new Vector3(x * , y * , );
//food.transform.localPosition = new Vector3( x, y, 0);
if(isReward==true)
{
GameObject reward = Instantiate(rewardPrefab);
reward.transform.SetParent(foodHolder, false);
x = Random.Range(-xlimit + xoffset, xlimit);
y = Random.Range(-ylimit, ylimit);
reward.transform.localPosition = new Vector3(x * , y * , );
}
} public void Home()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
}
FoodMaker.cs
场景UI控制脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class MainUIController : MonoBehaviour { //单例模式
private static MainUIController _instance;
public static MainUIController Instance
{
get
{
return _instance;
}
} public int score = ;
public int length = ;
public Text msgText;
public Text scoreText;
public Text lengthText;
public Image bgImage;
private Color tempColor; public Image pauseImage;
public Sprite[] pauseSprites;
public bool isPause = false ;
public bool hasBorder = true; void Awake()
{
_instance = this;
} void Start()
{
if (PlayerPrefs.GetInt("border", )==)
{
hasBorder = false;
//取消边界上的颜色
foreach(Transform t in bgImage.gameObject.transform)
{
t.gameObject.GetComponent<Image>().enabled = false;
}
}
} private void Update()
{
switch (score / )
{
case :
case :
case :
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF",out tempColor);
bgImage.color=tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCEEFFFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#CCFFDBFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
ColorUtility.TryParseHtmlString("#EBFFCCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段" + ;
break;
case :
case :
case :
ColorUtility.TryParseHtmlString("#FFDACCFF", out tempColor);
bgImage.color = tempColor;
msgText.text = "阶段 x";
break;
}
} public void UpdateUI(int s = ,int l = )
{
score += s;
length += l;
scoreText.text ="得分:\n"+score;
lengthText.text = "长度\n" + length;
} public void Pause()
{
isPause = !isPause;
if(isPause)
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
else
{
Time.timeScale = ;
pauseImage.sprite = pauseSprites[];
}
}
}
MainUIController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI; public class StartUIController : MonoBehaviour { public Text lastText;
public Text bestText;
public Toggle blue;
public Toggle yellow;
public Toggle border;
public Toggle noborder; private void Awake()
{
lastText.text = "上次:长度" + PlayerPrefs.GetInt("last1",) + ",分数" + PlayerPrefs.GetInt("lasts",);
bestText.text = "最好:长度" + PlayerPrefs.GetInt("best1", ) + ",分数" + PlayerPrefs.GetInt("bests",);
} private void Start()
{
if (PlayerPrefs.GetString("sh", "sh01") == "sh01")
{
blue.isOn = true;
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
else
{
yellow.isOn = true;
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
if (PlayerPrefs.GetInt("border", ) == )
{
border.isOn = true;
PlayerPrefs.SetInt("border",);
}
else
{
noborder.isOn = true;
PlayerPrefs.SetInt("border", );
}
} public void BlueSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh01");
PlayerPrefs.SetString("sb01", "sb0101");
PlayerPrefs.SetString("sb02", "sb0102");
}
} public void YellowSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetString("sh", "sh02");
PlayerPrefs.SetString("sb01", "sb0201");
PlayerPrefs.SetString("sb02", "sb0202");
}
} public void BorderSelected(bool isOn)
{
if (isOn)
{
PlayerPrefs.SetInt("border",);
}
} public void NoBorderSelected(bool isOn)
{
if (isOn)
{
//自由模式
PlayerPrefs.SetInt("border", );
}
} public void StartGame()
{
UnityEngine.SceneManagement.SceneManager.LoadScene();
}
}
StartUIController.cs
Unity3D_(游戏)贪吃蛇的更多相关文章
- Java小游戏贪吃蛇
package snake; import java.awt.BorderLayout;import java.awt.Canvas;import java.awt.Color;import java ...
- 用Canvas制作小游戏——贪吃蛇
今天呢,主要和小伙伴们分享一下一个贪吃蛇游戏从构思到实现的过程~因为我不是很喜欢直接PO代码,所以只copy代码的童鞋们请出门左转不谢. 按理说canvas与其应用是老生常谈了,可我在准备阶段却搜索不 ...
- 第一个windows 小游戏 贪吃蛇
最近用dx尝试做了一个小的贪吃蛇游戏,代码放到github上面:https://github.com/nightwolf-chen/MyFreakout 说一下自己实现的过程: 首先,我把蛇这个抽象成 ...
- Unity3D游戏贪吃蛇大作战源码休闲益智手机小游戏完整项目
<贪吃蛇大作战>一款休闲竞技游戏,不仅比拼手速,更考验玩家的策略. 视频演示: http://player.youku.com/player.php/sid/XMzc5ODA2Njg1Ng ...
- 使用JavaScript实现简单的小游戏-贪吃蛇
最近初学JavaScript,在这里分享贪吃蛇小游戏的实现过程, 希望能看到的前辈们能指出这个程序的不足之处. 大致思路 首先要解决的问题 随着蛇头的前进,尾巴也要前进. 用键盘控制蛇的运动方向. 初 ...
- Unity 3D游戏-贪吃蛇类游戏源码:重要方法和功能的实现
贪吃蛇类游戏源码 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 头部移动方式 2 生成 Shit 道具 ...
- JavaScript面向对象编程小游戏---贪吃蛇
1 面向对象编程思想在程序项目中有着非常明显的优势: 1- 1 代码可读性高.由于继承的存在,即使改变需求,那么维护也只是在局部模块 1- 2 维护非常方便并且成本较低. 2 这个demo是采用了 ...
- 最简单的HTML5游戏——贪吃蛇
<html> <head> <meta charset="UTF-8"/> <title>贪吃蛇</title> < ...
- c++小游戏——贪吃蛇
#include #include #include #include #include <conio.h> #include #include <windows.h> usi ...
随机推荐
- 5表联查yii框架权限控制
一:控制器部分 <?php namespace app\controllers; use yii\web\Controller; class PreController extends Cont ...
- layui2.5 修改layuicms
雷哥layui2.5版本学习 学习地址: https://www.bilibili.com/video/av59813890/?p=30 注意: 修改layuicms时注意下面是缓存的js, < ...
- Docker:Swarm + Stack 一站式部署容器集群
参考1 参考2 1.注意docker的版本,yum默认安装的版本比较低,可能出现 unsupported Compose file version: 3.7 docker版本升级 2.docker-c ...
- luogu题解 P2419 【牛大赛Cow Contest】传递丢包
题目链接: https://www.luogu.org/problemnew/show/P2419 分析: "在交际网络中,给定若干元素和若干对二元关系,且关系具有传递性. 通过传递性推导出 ...
- 常用CSS代码大全(工作必备)
用html+css可以很方便的进行网页的排版布局,但不是每一种属性或者代码我们都铭记于心,最近我把CSS中的常用代码进行了归纳总结,方便自己以后查看,同时也分享给大家,希望对你们有用. 一.文本设置 ...
- O003、准备 KVM 实验环境
参考https://www.cnblogs.com/CloudMan6/p/5240770.html KVM 是 OpenStack 使用的最广泛的Hypervisor,本节介绍如何搭建 KVM ...
- Communication between C++ and Javascript in Qt WebEngine(转载)
Communication between C++ and Javascript in Qt WebEngine admin January 31, 2018 0 As Qt WebKit is re ...
- 15 Scrapy框架之CrawlSpider
一.简介 CrawlSpider其实是Spider的一个子类,除了继承到Spider的特性和功能外,还派生除了其自己独有的更加强大的特性和功能.其中最显著的功能就是”LinkExtractors链接提 ...
- 关于的 let 关键字的一个小问题
刚才在看阮一峰老师的<ES6标准入门>,在介绍 let 那一段时有这么一段话 我就自己在控制台试了一下这段代码,输出果然的是"abc",于是我就把代码稍微修改了下 也没 ...
- Hybrid APP架构设计
通讯 作为一种跨语言开发模式,通讯层是Hybrid架构首先应该考虑和设计的,往后所有的逻辑都是基于通讯层展开. Native(以Android为例)和H5通讯,基本原理: Android调用H5:通过 ...