俄罗斯方块 (作业九)

素材下载

作业需求

STARTO!

游戏画面设计

新建一个 2D Unity 专案

更改 MainCamera 颜色为黑色,大小调整为 8,位置 X = 4.5 ,Y = 7.5

将开头下载的素材丢进专案

选取两张图片

将每单位像素数改为 32

选取套用

拖曳两个 border.png 到阶层视窗

将 border 物件的位置 X = -0.5,Y = 10,缩放 Y = 40

将 border (1) 物件的位置 X = 9.5,Y = 10,缩放 Y = 40

将开头下载的 05_Swoosh.mp3 拉进专案视窗

将 MainCamera 增加元件>音讯>音讯源

将 AudioClip 设定为 05_Swoosh.mp3

在阶层视窗按下滑鼠右键>UI>文字

设定 Canvas 的渲染模式为萤幕空间 – 摄影机,渲染摄影机设为 MainCamera

设定 Text 物件的属性字型大小为30,颜色白色,水平与垂直溢出设定为 Overflow

调整一下 Text 的位置

画面设计完成

俄罗斯方块物件制作

在阶层视窗按下滑鼠右键>建立空物件

拉四次 block.png 到 Gameobject 底下

修改四个物件的位置属性如下

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = 1,Y = 0
  • block (3) 物件 X = 1,Y = 1

重新命名 GameObject 物件名称为 GroupO

将 GroupO 拉到专案资料夹制作预制物件

重复以上过程,制作 GroupI、GroupJ、GroupL、GroupS、GroupT、GroupZ

GroupI 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = 0,Y = 2
  • block (3) 物件 X = 0,Y = 3

GroupJ 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = 0,Y = 2
  • block (3) 物件 X = -1,Y = 0

GroupL 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = 0,Y = 2
  • block (3) 物件 X = 1,Y = 0

GroupS 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = 1,Y = 1
  • block (3) 物件 X = -1,Y = 0

GroupZ 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 0,Y = 1
  • block (2) 物件 X = -1,Y = 1
  • block (3) 物件 X = 1,Y = 0

GroupT 属性

  • block 物件 X = 0,Y = 0
  • block (1) 物件 X = 1,Y = 0
  • block (2) 物件 X = 2,Y = 0
  • block (3) 物件 X = 1,Y = -1

制作生成器 (Spawner)

在阶层视窗按下滑鼠右键>建立空物件

命名为 Spawner

设定 Spawner 属性,位置 X = 5,Y = 14

新建一个 Scripts 资料夹

建立一个脚本名为 Spawner.cs 并加入以下程式码

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Spawner : MonoBehaviour
{
    // Start is called before the first frame update
    public GameObject[] groups;
    void Start()
    {
        spwanNext();
    }

    public void spwanNext()
    {
        int i = UnityEngine.Random.Range(0, groups.Length);
        Instantiate(groups[i], transform.position, Quaternion.identity);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

储存脚本并将 Spawner.cs 脚本拉进 Spawner 物件底下

点下”组”

大小输入 7

将刚刚制作的七个预制物件拉进去

制作网格 (Grid) 与群组 (Group) 脚本

新建一个脚本 Grid_Scripts.cs 脚本,输入以下程式码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Grid_Scripts : MonoBehaviour
{
    // Start is called before the first frame update
    public static int w = 10;
    public static int h = 20;
    public static Transform[,] grid = new Transform[w, h];
    public static int score = 0;
    private static Text score_display;
    public static Vector2 roundVec2(Vector2 v)
    {
        return new Vector2(Mathf.Round(v.x), Mathf.Round(v.y));
    }
    public static bool insideBorder(Vector2 pos)
    {
        return ((int)pos.x >= 0 && (int)pos.x < w && (int)pos.y >= 0);
    }
    public static void deleteRow(int y)
    {
        for (int x = 0; x < w; ++x)
        {
            Destroy(grid[x, y].gameObject);
            grid[x, y] = null;
        }
    }
    public static void decreaseRow(int y)
    {
        for (int x = 0; x < w; ++x)
        {
            if (grid[x, y] != null)
            {
                grid[x, y - 1] = grid[x, y];
                grid[x, y] = null;
                grid[x, y - 1].position += new Vector3(0, -1, 0);
            }
        }
    }

    public static void decreaseRowAbove(int y)
    {
        for (int i = y; i < h; ++i)
        {
            decreaseRow(i);
        }
    }
    public static bool isRowFull(int y)
    {
        for (int x = 0; x < w; ++x)
        {
            if (grid[x, y] == null)
                return false;
        }
        return true;
    }
    public static void deleteFullRows()
    {
        for (int y = 0; y < h; ++y)
        {
            if (isRowFull(y))
            {
                score++;
                deleteRow(y);
                decreaseRowAbove(y + 1);
                --y;
                set_score();
            }
        }
    }

    static void set_score()
    {
        score_display = GameObject.Find("Text").GetComponent<Text>();
        score_display.text = score.ToString();
    }
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

新增一个 Group.cs 脚本,输入以下程式码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Group : MonoBehaviour
{
    // Start is called before the first frame update
    float lastFall = 0;

    bool isValidGridPos()
    {
        foreach (Transform child in transform)
        {
            Vector2 v = Grid_Scripts.roundVec2(child.position);
            if (!Grid_Scripts.insideBorder(v))
                return false;
            if (Grid_Scripts.grid[(int)v.x, (int)v.y] != null &&
                Grid_Scripts.grid[(int)v.x, (int)v.y].parent != transform)
                return false;
        }
        return true;
    }

    void updateGrid()
    {
        for (int y = 0; y < Grid_Scripts.h; ++y)
            for (int x = 0; x < Grid_Scripts.w; ++x)
                if (Grid_Scripts.grid[x, y] != null)
                    if (Grid_Scripts.grid[x, y].parent == transform)
                        Grid_Scripts.grid[x, y] = null;
        foreach (Transform child in transform)
        {
            Vector2 v = Grid_Scripts.roundVec2(child.position);
            Grid_Scripts.grid[(int)v.x, (int)v.y] = child;
        }
    }
    void Start()
    {
        if (!isValidGridPos())
        {
            Debug.Log("Game Over");
            Destroy(gameObject);
        }
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            transform.position += new Vector3(-1, 0, 0);
            if (isValidGridPos())
                updateGrid();
            else
                transform.position += new Vector3(1, 0, 0);
        }
        else if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            transform.position += new Vector3(1, 0, 0);
            if (isValidGridPos())
                updateGrid();
            else
                transform.position += new Vector3(-1, 0, 0);
        }
        else if(Input.GetKeyDown(KeyCode.UpArrow))
        {
            transform.Rotate(0, 0, -90);
            if (isValidGridPos())
                updateGrid();
            else
                transform.Rotate(0, 0, 90);
        }
        else if(Input.GetKeyDown(KeyCode.DownArrow) || Time.time - lastFall >= 1)
        {
            transform.position += new Vector3(0, -1, 0);
            if (isValidGridPos())
                updateGrid();
            else
            {
                transform.position += new Vector3(0, 1, 0);
                Grid_Scripts.deleteFullRows();
                FindObjectOfType<Spawner>().spwanNext();
                enabled = false;
            }
            lastFall = Time.time;
        }
    }
}

将七个预制物件选取起来

增加元件>脚本>Group

完成,看看结果吧! (上课资料)

完成,看看结果吧! (作业)

SHXJ
Latest posts by SHXJ (see all)

发布留言