俄罗斯方块大家应该都玩过,规则就不用介绍了,这里只是简单开发,高级程序还需要大家开发,用到的是c#和Unity开发。
我使用的unity2018版。
以下是要用到的素材:
 1.小方块
 
 
 
 
 
 
 方块一共有七种形态,其他形态都是通过这7中旋转得来的,所以只创建这七种。
 
 我们开始操作:
 将小方块拼成上面所示的形状
 
 创建一个Create Empty空物体,将四个物体放入空物体内,改名为T1,剩下的依次累加。
 将他们放入文件夹中。
 
 可以用方块拉长作为边界, 左边界Position的x值为-0.65,右边界Position的x值为9.66
 单个方块的Scale的x,y值均为3.5后期方便运算
随机生成方块和分数显示
创建一个空物体,将该类附给他。
public class Builder : MonoBehaviour {
   
	public Text sText;
	public GameObject[] Default;
	void Start () {
   
		Aaa();
	}
	public void Aaa()
    {
   
    int i = Random.Range(0, Default.Length);//随机数
    GameObject ins = Instantiate(i], transform.position, transform.rotation);//实例化
    }
    void Update () {
   
		sText.text = Grid.j.ToString();//这个是分数显示文本
	}
}

方块的左移,右移,下移和旋转
public class Move : MonoBehaviour {
   
	public static float lastTime = 0;
    int k = 0;
    void Start () {
   
        if (!isValidGridPom())//判断游戏是否结束
        {
   
            Debug.Log(111);
            GameObject.Find("Canvas").GetComponent<Nmzx>().GameOver();
            Destroy(gameObject);
        }
	}
	
	// Update is called once per frame
	void Update () {
   
		if (Input.GetKeyDown(KeyCode.A))//按A键左移
        {
   
			transform.position += new Vector3(-1, 0,0);
            if (isValidGridPom())//若到达边界,按A键,先向左移动一格再向右移动一格,则不会移动,下面皆同理
            {
   
                Data();
            }
            else
            {
   
                transform.position += new Vector3(1, 0, 0);
            }
        }
        else if (Input.GetKeyDown(KeyCode.D))
        {
   
			transform.position += new Vector3(1, 0, 0);
            if (isValidGridPom())
            {
   
                Data();
            }
            else
            {
   
                transform.position += new Vector3(-1, 0, 0);
            }
        }
        else if (Input.GetKeyDown(KeyCode.S) ||
			Time.time - lastTime >= 1)//按S键和时间差>=1时向下移动一个格
        {
   
			transform.position += new Vector3(0, -1, 0);
            if (isValidGridPom())
            {
   
                Data();
            }
            else
            {
   
                transform.position += new Vector3(0, 1, 0);
                //调用实例化
                Grid.deleteFullRow();//若方块落下去
                FindObjectOfType<Builder>().Aaa();//实例化
                enabled = false;
            }
            lastTime = Time.time;
        }
        else if (Input.GetKeyDown(KeyCode.W))
        {
   
			transform.Rotate(0, 0, -90);
            if (isValidGridPom())
            {
   
                Data();
            }
            else
            {
   
                transform.Rotate(0, 0, 90);
            }
        }
	}
通过这个可以发现,方块虽然移动,但一直向下掉,所以我们写一个边界类
边界和消除
通过二维数组将区域分为好多小方块,以便消除和形成边界。
public class Grid : MonoBehaviour {
   
	public static int w = 10;
	public static int h = 20;
	public static  int j = 0;
	public static Transform[,] grid = new Transform[w, h];
	public static Vector2 roundVec2(Vector2 v)
    {
   
		return new Vector2(Mathf.Round(v.x), Mathf.Round(v.y));
    }
	// Use this for initialization
	void Start () {
   
	}
	
	// Update is called once per frame
	void Update () {
   
		
	}
	//保证每个被检查的位置不小于左边框,不大于右边框,不小于最小的y
	public static bool insideBorder(Vector2 pos)
    {
   
		return (pos.x >= 0 
			&& pos.x < w 
			&& pos.y >= 0);
    }
	public static bool isRowFull(int y)
	{
   
		for (int i = 0; i < w; ++i)
		{
   
            if (grid[i,y] ==null)
            {
   
				return false;
            }
		}
		return true;
	}
	public static void deleteRow(int y)
    {
   
        for (int i = 0; i < w; ++i)
        {
   
			Destroy(grid[i, y].gameObject);
			
			grid[i, y] = null;
        }
		j++;
	}
	//将方块向下移动
	public static void decreaseRow(int y)
    {
   
        for (int i = 0; i < w; ++i)
        {
   
            if (grid [i,y] != null)
            {
   
				grid[i, y - 1] = grid[i, y];
				grid[i, y] = null;
				grid[i, y - 1].position += new Vector3(0, -1, 0);
            }
        }
    }
	
	public static void decrease(int y)
    {
   
        for (int i = y; i < h; i++)
        {
   
			decreaseRow(i);
        }
    }
	public  static void deleteFullRow()
    {
   
        for (int i = 0; i < h; i++)
        {
   
            if (isRowFull(i))
            {
   
				deleteRow(i);
				decrease(i + 1);
            }
            else
				i++;
        }
    }
}
接下来在Move类中写判断生成的方块是否在游戏区域和方块在区域中的位置更新
 //判断是否在格子里
     bool isValidGridPom()
     {
   
        foreach (Transform child in transform)
        {
   
            Vector2 v = Grid.roundVec2(child.position);
            //判断是否在边境之内(左、右、下)
            if (!Grid.insideBorder(v))
            {
   
                return false;
            }
            //2.现在的grid对应的格子里面是null
            if (Grid.grid[(int)v.x, (int)v.y] != null && Grid.grid[(int)v.x, (int)v.y].parent != transform)
            {
   
                return false;
            }
        }
        return true;
    }
//更新方块在区域中的位置信息,以便消除和累积
   void Data()
    {
   
        for (int i = 0; i < Grid.h; i++)
        {
   
            for (int x = 0; x < Grid.w; x++)
            {
   
                if (Grid.grid[x, i] != null)
                {
   
                    if (Grid.grid[x,i].parent == transform)
                    {
   
                        Grid.grid[x, i] = null;
                    }
                }
            }
        }
        //
        foreach(Transform child in transform)
        {
   
            Vector2 v = Grid.roundVec2(child.position);
            Grid.grid[(int)v.x, (int)v.y] = child;
        }
    }
最后写游戏结束画面

 最后写一个游戏结束类,将该类赋给Canvas,将Image拖入实例化对象
 
public class Nmzx : MonoBehaviour {
   
	public GameObject gameOverUI;
	bool isEnd = false;
	// Use this for initialization
	void Start () {
   
		
	}
	
	// Update is called once per frame
	void Update () {
   
		//if (isEnd) return;
       
	}
	public void GameOver()
    {
   
		gameOverUI.SetActive(true);
		//isEnd = true;
    }
}
当前代码只能支持一次消除一行和时间计时功能,若需要消除多行需自己完善。
感谢大家捧场
转载:https://blog.csdn.net/m0_47605113/article/details/109111715
查看评论
					