|
效果图:
思路:贪吃蛇的玩法核心是玩家控制一个方块 去吃另一个方块,吃掉的方块变成自己的身体跟随上一个方块移动,吃的越多速度越快,游戏结束判断是否撞到墙壁或者撞到自己的身体
一、场景布局
1.相机设置
修改相机参数 :ClearFlags 设置为SolidColor 让我们游戏中的场景纯颜色显示 ,Projection设置为Orthographic 正交相机 , size 设置相机视角的大小
2.场景设置
设置游戏背景图、四面的墙壁、贪吃蛇的蛇头和食物的组件及属性,还有一个游戏失败和显示分数的UI界面。
①背景图:新建2D Object-->Sprite 取名GameBG 设置图片精灵 调整scale大小为30*30 作
围墙Wall :设置Tag标签为Wall(用于判断撞到墙死亡)设置碰撞盒, 复制三个围墙调整大小位置
②贪吃蛇的蛇头 SnakePlayer 添加刚体Rigidbody2D和BoxColider2D组件,这里注意将2D刚体组件的Gravity Scale重力规模设置为0 (平面移动不需要重力) ,调整位置xy为0.5(为啥要调整为0.5 下面会有解释说明)
③创建食物 :FoodPool当作食物存放的对象池,创建食物添加BoxColider2D组件 设置Tag为Food(用于碰撞检测),与蛇头一样调整位置xy为0.5
为什么蛇头和食物要设置position位置为0.5?
因为我们创建的蛇和食物都是scale为1*1的矩形 我们移动的位置想要它跟场景方块对其 需要设置其初始位置为0.5(即:scale/2 大小的一半),其实也可以不用设置 小编有点强迫症对其好看就,嘿嘿......
④设置UI界面
创建空物体UIManager当作节点容器 存放组件,左上角Text为分数,RefreshPanel游戏失败背景UI 新建一个Text作为游戏失败文字, 一个Button作为重新开始按钮。
二、功能实现
1.首先制作蛇的移动功能,新建脚本PlayerMovement.cs 贪吃蛇的所有功能都放在这个脚本中
贪吃蛇功能:
①蛇的移动是自动的 我们只需要控制蛇的左右或上下移动的方向即可,
②蛇在往左(或往下)移动时 ,我们不能操作蛇往右(或往左)移动。
③蛇头在触发了食物时吃掉食物,触发了墙或自己的身体时游戏结束
了解了移动方式那我们开始编写功能吧。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- //方向类型
- public enum DirectionType
- {
- Horizontal, Vertical
- }
- public class PlayerMovement : MonoBehaviour
- {
- public static Vector3 direction = new Vector3(1, 0, 0);//移动方向
- public float currentTimespeed; //当前移动速度时间(时间越小 速度越快 这里我通过时间来加快速度)
- public float timerSpeedRatio;//每次吃到食物所减去的时间(即:贪吃蛇加速)
- float timer;//用于时间计算
- bool isDie = false;//是否死亡
- int foodnumber = 0;//吃掉的食物数量
- //食物 食物对象池
- public FoodData foodPrefab;
- public Transform foodPool;
- //贪吃蛇容器 用于存储吃掉的食物变成的身体
- public Transform snakePool;
- //游戏地图
- public Transform GameBG;
- void Start()
- {
- //初始化timer
- timer = currentTimespeed;
- //初始化位置
- transform.position = new Vector3(0.5f, 0.5f, 1);
- }
- void Update()
- {
- //玩家移动
- float h = Input.GetAxis("Horizontal");
- float V = Input.GetAxis("Vertical");
- //判断移动方向
- if (h != 0)
- {
- SetDirection(DirectionType.Horizontal, h);
- }
- if (V != 0)
- {
- SetDirection(DirectionType.Vertical, V);
- }
- //未死亡 执行移动
- if (!isDie)
- {
- Move();
- }
- }
- //修改方向
- private void SetDirection(DirectionType directionType, float _direction)
- {
- //判断水平的左右移动 或 垂直的上下移动
- float value = _direction > 0 ? 1f : -1f;
- //判断方向类型 设置移动方向
- switch (directionType)
- {
- case DirectionType.Horizontal:
- if (direction.x==0)
- {
- direction = new Vector2(value, 0);
- }
- break;
- case DirectionType.Vertical:
- if (direction.y==0)
- {
- direction = new Vector2(0, value);
- }
- break;
- default:
- break;
- }
- }
- //移动
- private void Move()
- {
- timer -= Time.deltaTime;
- if (timer < 0)
- {
- //执行移动
- GetComponent<FoodData>().Move(transform.position + direction);
- timer = currentTimespeed;
- }
- }
- //检测(需要 FoodData和UIManager脚本)
- void OnTriggerEnter2D(Collider2D col)
- {
- //判断是否触发了墙或者是自己
- if (col.transform.tag.Equals("Wall") || col.transform.tag.Equals("Player"))
- {
- //死亡
- isDie = true;
- UIManager.uiMagr.DieUI();
- }
- //食物
- if (col.transform.tag.Equals("Food"))
- {
- //判断贪吃蛇有没有身体
- if (snakePool.childCount > 0)
- {
- col.transform.GetComponent<FoodData>().SetDataInt(snakePool.GetChild(snakePool.childCount - 1).GetComponent<FoodData>());
- }
- if (snakePool.childCount <= 0)
- {
- col.transform.GetComponent<FoodData>().SetDataInt(GetComponent<FoodData>());
- }
- col.transform.SetParent(snakePool);
- if (col.transform== snakePool.GetChild(0))
- {
- col.transform.tag = "Untagged";
- }
- else
- {
- col.transform.tag = "Player";
- }
- //创建食物
- CreatFood();
- //加速
- currentTimespeed -= timerSpeedRatio;
- if (currentTimespeed<=0.1f)
- {
- currentTimespeed = 0.1f;
- }
- //UI
- foodnumber++;
- UIManager.uiMagr.SetNumber(foodnumber);
- }
-
- }
- //创建食物
- public void CreatFood()
- {
- //基础值
- float basePos = 0.5f;
- int h_value = (int)(GameBG.localScale.x / 2);
- int v_value = (int)(GameBG.localScale.y / 2);
- int h = Random.Range(-h_value, h_value + 1);
- int v = Random.Range(-v_value, v_value + 1);
- Vector2 pos = new Vector2(h + 0.5f, v + 0.5f);
- if (pos.x > 15)
- {
- pos = new Vector2(h_value - 0.5f, pos.y);
- }
- if (pos.y > 15)
- {
- pos = new Vector2(pos.x, v_value - 0.5f);
- }
- GetFood(0).position = pos;
- }
- //获取食物
- public Transform GetFood(int index)
- {
- Transform food;
- if (index <= foodPool.childCount)
- {
- food = Instantiate(foodPrefab.transform, foodPool);
- }
- else
- {
- food = foodPool.GetChild(index);
- }
- return food;
- }
- }
复制代码 代码中有详细的解释,直接复制代码会出现问题,原因是需要FoodData.cs和UIManager.cs脚本中的方法.
设置贪吃蛇的初始属性
2.创建食物(和身体)属性脚本FoodData 将脚本拖给给SnakePlayer和food
这个食物脚本,在被蛇吃掉之后变成蛇的身体。
功能介绍:
①基础属性 移动前的位置信息,上一级物体,下一级物体。
②当食物被吃掉时,要获取蛇的最后一个身体,当作自己的上一级,上一级移动后,下一级移动到上一级移动前的位置
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- public class FoodData : MonoBehaviour
- {
- public Vector3 oldPos;//记录上一次移动
- public FoodData parentObj;//获取身体部位的上一个身体部位属性(用于贪吃蛇移动时,下一个方块移动到上一个方块的位置)
- public FoodData newObj;//记录下一个身体部位属性(用于当前身体移动后 调用下一个物体的移动方法)
- void Start()
- {
-
- }
- // Update is called once per frame
- void Update()
- {
-
- }
- //获取上一个物体(食物被吃掉时调用)
- public void SetDataInt(FoodData obj)
- {
- parentObj = obj;
- //设置上一个物体的newobj为自己
- parentObj.newObj = this;
- //食物被吃掉变成白色
- transform.GetComponent<SpriteRenderer>().color = Color.white;
- //位置初始化
- transform.position = parentObj.oldPos;
- }
- //移动 (用于当前物体移动完后执行下一个物体的移动)
- public void Move()
- {
- //记录上一次移动位置(这个值 下一个物体移动时所需)
- oldPos=transform.position;
- //修改位置
- transform.position = parentObj.oldPos;
- //执行下一个物体的移动命令
- if (newObj!=null)
- {
- newObj.Move();
- }
- }
- //移动(蛇的头部移动 需要传参)
- public void Move(Vector3 pos)
- {
- oldPos = transform.position;
- //修改位置
- transform.position = pos;
- if (newObj != null)
- {
- newObj.Move();
- }
- }
- }
复制代码 3.脚本UIManager.cs 拖给空物体UIManager- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine.UI;
- using UnityEngine;
- using UnityEngine.SceneManagement;//加载场景时需引用
- public class UIManager : MonoBehaviour
- {
- public static UIManager uiMagr;
- public Text number_txt;//分数
- public Button refreshBtn;//重新开始按钮
- public Transform dieUI;//游戏失败面板
- void Start()
- {
- //初始化
- uiMagr = this;
- dieUI.gameObject.SetActive(false);
- refreshBtn.onClick.AddListener(Refresh);
- }
- // Update is called once per frame
- void Update()
- {
- //按下esc 退出程序
- if (Input.GetKeyDown(KeyCode.Escape))
- {
- Application.Quit();
- }
- }
- //修改分数值
- public void SetNumber(int value)
- {
- number_txt.text = value.ToString();
- }
- //显示死亡UI
- public void DieUI()
- {
- dieUI.gameObject.SetActive(true);
- }
- //刷新
- void Refresh()
- {
- //重新加载场景
- SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
- }
- }
复制代码 链接:https://pan.baidu.com/s/1bGXUal8RIJBSb6oFq4zHPA
提取码:syq1
<div id="marketingBox" class="marketing-box"><div class="marketing-content">
开发者涨薪指南
48位大咖的思考法则、工作方式、逻辑体系 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|