——创建每一个方块可移动到的位置点,可以理解为创建一个游戏地图,从(0,0)点开始依次向x轴和y轴延伸,例如x最大为9,y最大为19,则创建了一个20行10列的地图 ——制作每一个形状的预制体,Shape是每一个整体形状,Block是每一块小方块,CenterPos代表这个形状的旋转中心 ——创建GameController脚本控制游戏逻辑,挂载到面板物体上。创建Shape脚本控制每个形状的操作,挂载到每个形状上 ——在GameController脚本中编写生成形状的逻辑 ——在Shape脚本中编写形状下落的逻辑 ——但是此时形状是可以无限下落的,到达底部也不会停止下落,所以我们需要编写判定能否下落的方法 ——在形状下落的方法中添加判断去控制是否能够下落 ——现在形状与形状之间并不会叠加,而是会重叠在一起,在GameController脚本中编写方法,将每个方块位置添加到地图数组中(注意必须对每个方块的位置进行四舍五入取整操作) ——当形状下落到底部时,将每一个方块的位置添加到地图数组中 ——控制形状的左右移动 ————控制形状的旋转 ——控制加速下落 ——判断整行的消除 ——判断游戏是否失败 ——GameController脚本,控制游戏整体逻辑 ——Shape脚本,控制每个形状的操作 一:演示
二:实现思路
//当前方块 public Shape CurShape { get; set; } private void Update() { if (CurShape == null) { SpawnBlock(); } } /// <summary> /// 生成方块 /// </summary> private void SpawnBlock() { int randomType = Random.Range(1, 8); GameObject shape = Instantiate(Resources.Load<GameObject>("Prefabs/Item/Shape" + randomType)); CurShape = shape.GetComponent<Shape>(); CurShape.transform.SetParent(transform); CurShape.transform.position = new Vector2(4, 20); }
private float fallTimer;//下落的计时器 private float fallTimeval = 0.5f;//下落的时间间隔 private void Update() { //控制下落 if (fallTimer >= fallTimeval) { //下落 Fall(); fallTimer = 0; } else { fallTimer += Time.deltaTime; } } /// <summary> /// 下落 /// </summary> private void Fall() { Vector3 curPos = transform.position; Vector3 targetPos = curPos; targetPos.y -= 1; transform.position = targetPos; }
在GameController脚本编写方法判定能否下落的逻辑,需要判定两点,每个方块的位置是否到达边界和每个方块的位置是否存在于地图数组中,注意必须对每个方块的位置进行四舍五入取整操作
public const int row_max = 23; public const int column_max = 10; public Transform[,] mapArray = new Transform[column_max, row_max];//地图数组(保存每个方块的位置信息) /// <summary> /// 判断是否为合法的位置 /// </summary> /// <param name="shape">每一个形状</param> /// <returns></returns> public bool IsValidPos(Transform shape) { foreach (Transform block in shape.transform) { if (block.GetComponent<SpriteRenderer>() == null) continue; Vector2 blockPos = block.transform.position; blockPos = new Vector2(Mathf.RoundToInt(blockPos.x), Mathf.RoundToInt(blockPos.y)); if (IsBorder(blockPos) || mapArray[(int)blockPos.x, (int)blockPos.y] != null) { return false; } } return true; } /// <summary> /// 判断是否到达边界 /// </summary> /// <param name="pos">每一个方块的位置</param> /// <returns></returns> private bool IsBorder(Vector2 blockPos) { if (blockPos.x < 0 || blockPos.x >= column_max || blockPos.y < 0) { return true; } return false; }
private bool canFall = true;//能否下落 /// <summary> /// 下落 /// </summary> private void Fall() { if (canFall == false) { return; } Vector3 curPos = transform.position; Vector3 targetPos = curPos; targetPos.y -= 1; transform.position = targetPos; if (GameController.Instance.IsValidPos(transform) == false) { targetPos.y += 1; transform.position = targetPos; FallToBottom(); } } /// <summary> /// 下落到了底部 /// </summary> private void FallToBottom() { canFall = false; GameController.Instance.CurBlock = null; }
/// <summary> /// 将每个方块位置添加到地图数组中 /// </summary> /// <param name="shapeTran"></param> public void AddEachBlockTransToMapArray(Transform shape) { foreach (Transform block in shape.transform) { if (block.GetComponent<SpriteRenderer>() == null) { continue; } Vector2 blockPos = block.position; blockPos = new Vector2(Mathf.RoundToInt(blockPos.x), Mathf.RoundToInt(blockPos.y)); mapArray[(int)blockPos.x, (int)blockPos.y] = block; } }
/// <summary> /// 下落到底部 /// </summary> private void FallToBottom() { canFall = false; GameController.Instance.CurShape = null; //方块下落到底部时将每个方块位置添加到地图数组中 GameController.Instance.AddEachBlockTransToMapArray(transform); }
private void Update() { //控制左右移动 ControlMovement(); } /// <summary> /// 控制左右移动 /// </summary> private void ControlMovement() { float h = 0; if (Input.GetKeyDown(KeyCode.RightArrow)) { h = 1; } else if (Input.GetKeyDown(KeyCode.LeftArrow)) { h = -1; } Vector3 curPos = transform.position; Vector3 targetPos = curPos; targetPos.x += h; transform.position = targetPos; if (GameController.Instance.IsValidPos(transform) == false) { targetPos.x -= h; transform.position = targetPos; } }
private void Update() { //控制旋转 ControlRotate(); } /// <summary> /// 控制旋转 /// </summary> private void ControlRotate() { if (Input.GetKeyDown(KeyCode.UpArrow)) { Transform rotateTrans = transform.Find("CenterPos"); transform.RotateAround(rotateTrans.position, Vector3.forward, -90); if (GameController.Instance.IsValidPos(transform) == false) { transform.RotateAround(rotateTrans.position, Vector3.forward, 90); } } }
private void Update() { //控制加速下落 ControlUpspeed(); } /// <summary> /// 控制加速 /// </summary> private void ControlUpspeed() { if (Input.GetKeyDown(KeyCode.DownArrow)) { fallTimeval = 0.05f; } if (Input.GetKeyUp(KeyCode.DownArrow)) { fallTimeval = 0.5f; } }
先去判断是否有行满了,如果有则进行消除操作,消除时先删除掉当前行的每一个方块再将地图数组中当前行置空,之后再将满的行的上面行依次向下移动一行
/// <summary> /// 检查是否有行满了 /// </summary> private void CheckRowFull() { for (int row = 0; row < row_max; row++) { bool isFull = true; for (int column = 0; column < column_max; column++) { if (mapArray[column, row] == null) { isFull = false; break; } } //如果有行满了 if (isFull) { //————————————————————消除操作 ClearRow(row); MoveDownRow(row + 1); row--; } } } /// <summary> /// 清除行 /// </summary> /// <param name="row">清除的行(满的行)</param> private void ClearRow(int _row) { for (int coloum = 0; coloum < column_max; coloum++) { Destroy(mapArray[coloum, _row].gameObject); mapArray[coloum, _row] = null; } } /// <summary> /// 将清除的行上面的每一行依次向下移动一行 /// </summary> /// <param name="row">依次移动的起始行(清除的行的上面一行)</param> private void MoveDownRow(int _row) { for (int row = _row; row < row_max; row++) { for (int column = 0; column < column_max; column++) { if (mapArray[column, row] != null) { mapArray[column, row - 1] = mapArray[column, row]; mapArray[column, row] = null; mapArray[column, row - 1].position -= Vector3.up; } } } }
/// <summary> /// 判断游戏失败 /// </summary> /// <returns></returns> private bool IsGameover() { for (int row = row_max - 3; row < row_max; row++) { for (int column = 0; column < column_max; column++) { if (mapArray[column, row] != null) { return true; } } } return false; }
三:完整代码
using UnityEngine; public class GameController : MonoSingleton<GameController> { public const int row_max = 23; public const int column_max = 10; private Transform[,] mapArray; //当前方块 public Shape CurShape { get; set; } /// <summary> /// 初始化数据 /// </summary> public void InitData() { mapArray = new Transform[column_max, row_max]; } /// <summary> /// 清空地图 /// </summary> public void ClearMap() { for (int row = 0; row < row_max; row++) { for (int column = 0; column < column_max; column++) { if (mapArray[column, row] != null) { Destroy(mapArray[column, row].gameObject); mapArray[column, row] = null; } } } } private void Update() { //if (GameManager.Instance.IsPause) //{ // return; //} if (CurShape == null) { SpawnBlock(); } } /// <summary> /// 生成方块 /// </summary> private void SpawnBlock() { Color randomColor = Random.ColorHSV(); int randomType = Random.Range(1, 8); GameObject shape = Instantiate(Resources.Load<GameObject>("Prefabs/Item/Shape" + randomType)); CurShape = shape.GetComponent<Shape>(); CurShape.transform.SetParent(transform); CurShape.Init(new Vector2(4, 20), randomColor); } /// <summary> /// 判断是否为合法的位置 /// </summary> /// <param name="shape">每一个形状</param> /// <returns></returns> public bool IsValidPos(Transform shape) { foreach (Transform block in shape.transform) { if (block.GetComponent<SpriteRenderer>() == null) continue; Vector2 blockPos = block.transform.position; blockPos = new Vector2(Mathf.RoundToInt(blockPos.x), Mathf.RoundToInt(blockPos.y)); if (IsBorder(blockPos) || mapArray[(int)blockPos.x, (int)blockPos.y] != null) { return false; } } return true; } /// <summary> /// 判断是否到达边界 /// </summary> /// <param name="pos">每一个方块的位置</param> /// <returns></returns> private bool IsBorder(Vector2 blockPos) { if (blockPos.x < 0 || blockPos.x >= column_max || blockPos.y < 0) { return true; } return false; } /// <summary> /// 将每个方块位置添加到地图数组中 /// </summary> /// <param name="shapeTran"></param> public void AddEachBlockTransToMapArray(Transform shape) { foreach (Transform block in shape.transform) { if (block.GetComponent<SpriteRenderer>() == null) { continue; } Vector2 blockPos = block.position; blockPos = new Vector2(Mathf.RoundToInt(blockPos.x), Mathf.RoundToInt(blockPos.y)); mapArray[(int)blockPos.x, (int)blockPos.y] = block; } //检查是否有行满了 CheckRowFull(); } /// <summary> /// 检查是否有行满了 /// </summary> private void CheckRowFull() { for (int row = 0; row < row_max; row++) { bool isFull = true; for (int column = 0; column < column_max; column++) { if (mapArray[column, row] == null) { isFull = false; break; } } //如果有行满了 if (isFull) { //————————————————————消除操作 ClearRow(row); MoveDownRow(row + 1); row--; } } } /// <summary> /// 清除行 /// </summary> /// <param name="row">清除的行(满的行)</param> private void ClearRow(int _row) { for (int coloum = 0; coloum < column_max; coloum++) { Destroy(mapArray[coloum, _row].gameObject); mapArray[coloum, _row] = null; } UIManager.Instance.FindUI<UI_Game>().UpdateCurScore(); } /// <summary> /// 将清除的行上面的每一行依次向下移动一行 /// </summary> /// <param name="row">依次移动的起始行(清除的行的上面一行)</param> private void MoveDownRow(int _row) { for (int row = _row; row < row_max; row++) { for (int column = 0; column < column_max; column++) { if (mapArray[column, row] != null) { mapArray[column, row - 1] = mapArray[column, row]; mapArray[column, row] = null; mapArray[column, row - 1].position -= Vector3.up; } } } } /// <summary> /// 判断游戏失败 /// </summary> /// <returns></returns> public bool IsGameover() { for (int row = row_max - 3; row < row_max; row++) { for (int column = 0; column < column_max; column++) { if (mapArray[column, row] != null) { return true; } } } return false; } }
using UnityEngine; public class Shape : MonoBehaviour { private bool canFall = true;//能否下落 private float fallTimer;//下落的计时器 private float fallTimeval = 0.5f;//下落的时间间隔 /// <summary> /// 初始化形状 /// </summary> /// <param name="pos"></param> /// <param name="color"></param> public void Init(Vector2 pos, Color color) { transform.position = pos; foreach (Transform child in transform) { if (child.GetComponent<SpriteRenderer>() != null) { child.GetComponent<SpriteRenderer>().color = color; } } } private void Update() { if (canFall == false) { return; } //控制下落 if (fallTimer >= fallTimeval) { //下落 Fall(); fallTimer = 0; } else { fallTimer += Time.deltaTime; } //控制加速下落 ControlUpspeed(); //控制左右移动 ControlMovement(); //控制旋转 ControlRotate(); } /// <summary> /// 控制左右移动 /// </summary> private void ControlMovement() { float h = 0; if (Input.GetKeyDown(KeyCode.RightArrow)) { h = 1; } else if (Input.GetKeyDown(KeyCode.LeftArrow)) { h = -1; } Vector3 curPos = transform.position; Vector3 targetPos = curPos; targetPos.x += h; transform.position = targetPos; if (GameController.Instance.IsValidPos(transform) == false) { targetPos.x -= h; transform.position = targetPos; } } /// <summary> /// 控制旋转 /// </summary> private void ControlRotate() { if (Input.GetKeyDown(KeyCode.UpArrow)) { Transform rotateTrans = transform.Find("CenterPos"); transform.RotateAround(rotateTrans.position, Vector3.forward, -90); if (GameController.Instance.IsValidPos(transform) == false) { transform.RotateAround(rotateTrans.position, Vector3.forward, 90); } } } /// <summary> /// 控制加速 /// </summary> private void ControlUpspeed() { if (Input.GetKeyDown(KeyCode.DownArrow)) { fallTimeval = 0.05f; } if (Input.GetKeyUp(KeyCode.DownArrow)) { fallTimeval = 0.5f; } } /// <summary> /// 下落 /// </summary> private void Fall() { Vector3 curPos = transform.position; Vector3 targetPos = curPos; targetPos.y -= 1; transform.position = targetPos; if (GameController.Instance.IsValidPos(transform) == false) { targetPos.y += 1; transform.position = targetPos; FallToBottom(); } } /// <summary> /// 下落到底部 /// </summary> private void FallToBottom() { canFall = false; GameController.Instance.CurShape = null; //方块下落到底部时将每个方块位置添加到地图数组中 GameController.Instance.AddEachBlockTransToMapArray(transform); if (GameController.Instance.IsGameover()) { GameManager.Instance.Gameover(); } } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算