Unity实现俄罗斯方块游戏

2020-06-21 13:00:01王振洲

本文实例为大家分享了Unity实现俄罗斯方块游戏的具体代码,供大家参考,具体内容如下

一、演示

二、实现思路

创建每一个方块可移动到的位置点,可以理解为创建一个游戏地图,从(0,0)点开始依次向x轴和y轴延伸,例如x最大为9,y最大为19,则创建了一个20行10列的地图

制作每一个形状的预制体,Shape是每一个整体形状,Block是每一块小方块,CenterPos代表这个形状的旋转中心

创建GameController脚本控制游戏逻辑,挂载到面板物体上。创建Shape脚本控制每个形状的操作,挂载到每个形状上

在GameController脚本中编写生成形状的逻辑

//当前方块
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);
}

在Shape脚本中编写形状下落的逻辑

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;
}