Unityではじめてのテトリス風落ちゲー制作記 ~その3 落下ブロック表示編~

Unity

Unityでテトリス風落ちゲーを作ってみたいけど、何から手を付けていいか分からない。私もそんな一人です。ここでは、自分の勉強も含めて、簡単なテトリス風落ちゲーを制作していく過程を掲載していきます。

この連載を最後まで読めば、このようなテトリス風落ちゲーが1人で作れるようになります。

別ウィンドウで開く場合はこちら

今回は落下ブロック表示編として、落下ブロックをゲーム画面上に表示して一定時間毎に1マス落下させるところまで解説していきます。

まだ壁ブロック表示編を読んでない方は、こちらを先に読むことをお勧めします。

この記事はこんな人におすすめ!

  • 用意されたアセットを極力使わず、自分の力でゲームを作りたい
  • プログラミング初心者で1つ1つ丁寧に解説した記事が読みたい
  • Unity初心者がスキルを上げながらゲームを制作していく過程を見たい

ゲーム制作方法は自己流です。もっと簡単に作る方法もあると思いますので、ご了承下さい。

落下ブロックの配列作成

ゲーム設計編で下の8種類のブロックをゲームに使用すると定義しました。

FallBlockSetというクラスを作り、落下ブロックの配列を定義していきます。

public class FallBlockSet
{
    private int[,] block00 = new int[4,4]{
        {0,2,0,0},
        {2,2,2,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block01 = new int[4,4]{
        {0,2,0,0},
        {0,2,2,0},
        {0,2,0,0},
        {0,0,0,0}
    };
    
    private int[,] block02 = new int[4,4]{
        {2,2,2,0},
        {0,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block03 = new int[4,4]{
        {0,2,0,0},
        {2,2,0,0},
        {0,2,0,0},
        {0,0,0,0}
    };

    private int[,] block10 = new int[4,4]{
        {0,2,2,0},
        {0,2,0,0},
        {0,2,0,0},
        {0,0,0,0}
    };

    private int[,] block11 = new int[4,4]{
        {0,0,0,0},
        {2,2,2,0},
        {0,0,2,0},
        {0,0,0,0}
    };

    private int[,] block12 = new int[4,4]{
        {0,2,0,0},
        {0,2,0,0},
        {2,2,0,0},
        {0,0,0,0}
    };

    private int[,] block13 = new int[4,4]{
        {2,0,0,0},
        {2,2,2,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block20 = new int[4,4]{
        {2,2,0,0},
        {0,2,0,0},
        {0,2,0,0},
        {0,0,0,0}
    };

    private int[,] block21 = new int[4,4]{
        {0,0,2,0},
        {2,2,2,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block22 = new int[4,4]{
        {0,2,0,0},
        {0,2,0,0},
        {0,2,2,0},
        {0,0,0,0}
    };

    private int[,] block23 = new int[4,4]{
        {0,0,0,0},
        {2,2,2,0},
        {2,0,0,0},
        {0,0,0,0}
    };

    private int[,] block30 = new int[4,4]{
        {2,2,0,0},
        {2,0,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block31 = new int[4,4]{
        {2,2,0,0},
        {0,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block32 = new int[4,4]{
        {0,2,0,0},
        {2,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block33 = new int[4,4]{
        {2,0,0,0},
        {2,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block40 = new int[4,4]{
        {2,0,0,0},
        {2,2,0,0},
        {0,2,0,0},
        {0,0,0,0}
    };

    private int[,] block41 = new int[4,4]{
        {0,2,2,0},
        {2,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block50 = new int[4,4]{
        {0,2,0,0},
        {2,2,0,0},
        {2,0,0,0},
        {0,0,0,0}
    };

    private int[,] block51 = new int[4,4]{
        {2,2,0,0},
        {0,2,2,0},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block60 = new int[4,4]{
        {0,2,0,0},
        {0,2,0,0},
        {0,2,0,0},
        {0,2,0,0}
    };

    private int[,] block61 = new int[4,4]{
        {0,0,0,0},
        {2,2,2,2},
        {0,0,0,0},
        {0,0,0,0}
    };

    private int[,] block70 = new int[4,4]{
        {2,2,0,0},
        {2,2,0,0},
        {0,0,0,0},
        {0,0,0,0}
    };
}

落下ブロックの配列を読み込むメソッドの作成

次に定義した落下ブロックの配列を読み込むsetメソッドを作ります。このsetメソッドもFallBlockSetクラス内に作成します。

public class FallBlockSet
{
    public int[,] set(int blockNum, int rot){
        if(blockNum == 0){
            if(rot == 0)        return block00;
            else if(rot == 1)   return block01;
            else if(rot == 2)   return block02;
            else                return block03;
        }
        else if(blockNum == 1){
            if(rot == 0)        return block10;
            else if(rot == 1)   return block11;
            else if(rot == 2)   return block12;
            else                return block13;
        }
        else if(blockNum == 2){
            if(rot == 0)        return block20;
            else if(rot == 1)   return block21;
            else if(rot == 2)   return block22;
            else                return block23;
        }
        else if(blockNum == 3){
            if(rot == 0)        return block30;
            else if(rot == 1)   return block31;
            else if(rot == 2)   return block32;
            else                return block33;
        }
        else if(blockNum == 4){
            if(rot == 0 | rot == 2) return block40;
            else                    return block41;

        }
        else if(blockNum == 5){
            if(rot == 0 | rot == 2) return block50;
            else                    return block51;

        }
        else if(blockNum == 6){
            if(rot == 0 | rot == 2) return block60;
            else                    return block61;

        }
        else if(blockNum == 7){
            return block70;
        } 
        else
        {
            return block00;
        }
    } 
}

第1引数blockNumに0~7の数字を入力することで8種類のブロックから表示させたいブロックを選択することが出来ます。第2引数rotはブロックの回転状態です。0: 回転なし、1: 90度回転、2: 180度回転、3: 270度回転になります。

落下ブロックを表示し、一定時間毎にブロックを落下させる

落下ブロックを表示し、一定時間毎にブロックを落下させるプログラムは以下の通りとなります。

壁ブロックを表示させるプログラムは省略していますので、ご了承下さい。

public float OX, OY; // ゲーム画面表示原点
public GameObject fallBlockPfb; // 落下ブロックPrefab
private GameObject[,] blockObj = new GameObject[21,14]; // 表示ブロックオブジェクト
private GameObject[,] fallBlockObj = new GameObject[4,4]; // 落下ブロックオブジェクト
private FallBlockSet fallBlockSet; // FallBlockSetクラス

private float fallCountTime; // 落下ブロックが1マス落下してからの経過時間

private static int fallBlockInitPosX = 4; // 落下ブロックの初期位置:X座標
private static int fallBlockInitPosY = 0; // 落下ブロックの初期位置:Y座標
private int fallBlockPosX; // 落下ブロックのX座標
private int fallBlockPosY; // 落下ブロックのY座標

private int[,] fallBlockStat = new int[4,4]; // 落下ブロック状態
private int blockNum; // ブロック種類
private int rot; // ブロック回転状態

private int[,] blockStat = new int[21,14]; // 各マスのブロック状態

void Start()
{
    fallBlockSet = new FallBlockSet(); // FallBlockSetクラスのインスタンス生成

    fallCountTime = 0;

    // 落下ブロック読み込み
    fallBlockPosX = fallBlockInitPosX;
    fallBlockPosY = fallBlockInitPosY;

    blockNum = Random.Range(0, 8);
    rot = 0;
    fallBlockStat = fallBlockSet.set(blockNum, rot);

}

void Update()
{
    // 落下ブロックを1秒毎に落下
    fallCountTime += Time.deltaTime;
    if(fallCountTime >= 1){
        fallBlockPosY++;
        fallCountTime = 0;
    }

    // 各マスのブロック状態に落下ブロックの状態を反映
    for(int i=0; i<4; i++){
        for(int j=0; j<4; j++){
            Destroy(fallBlockObj[j,i]);
            if(fallBlockStat[j,i] == 2){
                fallBlockObj[j,i] = Instantiate(fallBlockPfb, new Vector3(fallBlockPosX + i + OX, -fallBlockPosY -j + OY, 0), Quaternion.identity);  
            }
        }
    }
}

落下ブロックをランダムに表示させるようにしました。

落下ブロック表示プログラムはUpdateメソッドに記述し、1秒経過毎に落下ブロックを1マス下に移動させるようにしました。

Unityに戻り、Game ControllerコンポーネントのFall Block PfbにFall Blockプレハブをセットします。

では、ゲームを開始してみましょう!

現時点のゲーム動画はこちら↓になります。

単純に落下させているだけなので、壁ブロックを貫通し、一番下に移動後にエラーを吐き出しゲームが止まってしまいました。

まとめ

今回は、落下ブロックを表示し、一定時間毎にブロックを落下させるところまでを解説しました。

復習しますと

  • 落下ブロックの配列を定義
  • 落下ブロックの配列を読み込むメソッドを作成
  • 落下ブロックを表示し、一定時間毎にブロックを落下させる

です。

次回はプレイヤーがキー操作をしたときに、落下ブロックを左右に移動、回転、落下スピードを速めるプログラムを作成していきたいと思います。

最後までお読み頂きありがとうございました。