2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

簡易テトリスを作る!

Last updated at Posted at 2022-11-07

経緯

子供にUnity教える時に、テトリス作ってってよく言われるし作っとくかー

ブロックの回転は数学的知識が必要なのでわかりにくいかも...

URL

コード

できるだけObjectを少なくするように制作。ステージ、ミノは全て、一つのPrefabを使って制作した。

backGroundgenerator.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
using UnityEngine.UI;


public class backGroundgenerator : MonoBehaviour
{
    private GameObject backGroundBlock;
    private GameObject block;
    private GameObject none;

    public GameObject backGround;
    public GameObject Block;

    private List<List<GameObject>> backGroundList = new List<List<GameObject>>();
    private int[,] onOff = new int[10,10];

    private List<GameObject> movingBlock = new List<GameObject>();
    private int rotationKey;

    private Color[] colorList = new Color [7]{new Color(0,1,1,1),new Color(1,0.92f,0.016f,1),new Color(0,1,0,1),new Color(1,0,0,1),new Color(0,0,1,1),new Color(1,0.6471f,0,1),new Color(1,0,1,1)};
    //水色、黄色、緑、赤、青、オレンジ、マゼンダ

    private int random;

    private int score=0;
    public Text scoreText;
    // Start is called before the first frame update
    void Start()
    {
        scoreText.text="Score: "+score.ToString();
        for(int j = 0;j<10;j++){//盤面生成
            for(int i = 0;i<10;i++){
                if(j==0 || i==0 || i==9){
                    if(i==0){
                        backGroundList.Add(new List<GameObject>());
                    }
                    onOff[i,j]=1;
                    backGroundBlock  = (GameObject)Instantiate(backGround) as GameObject;
                    backGroundBlock.gameObject.transform.position = new Vector2(-4.5f+i,-4.5f+j);
                    backGroundList[j].Add(backGroundBlock);
                }else{
                    onOff[i,j]=0;
                    backGroundList[j].Add(none);
                }
            }
        }
        StartCoroutine (main());
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.RightArrow)){
            if(check("Right")){//右に進めるかチェック
                move("Right");//右に進める
            }
        }
        if(Input.GetKeyDown(KeyCode.LeftArrow)){
            if(check("Left")){
                move("Left");
            }
        }
        if(Input.GetKeyDown("d")){
            if(checkRotation("Right")){//右に回せるかチェック
                rotate("Right");//右に回す
            }
        }  
        if(Input.GetKeyDown("a")){
            if(checkRotation("Left")){
                rotate("Left");
            }
        } 
    }

    private IEnumerator main(){        
        while(true){    
            generate();//新しいブロック生成
            while(true){
                yield return new WaitForSeconds(1f);//一秒待つ
                if(check("Down")){//下に行けるかチェック
                    move("Down");//下に動かす
                }
                else{
                    changeToBackGround();//ブロックを動かせなくする
                    checkLine();//消せるラインがないか確認
                    break;
                }
            }
        }
    }
    private void generate(){
        random = Random.Range(0,6);
        if(random==0){//Iミノ
            for(int i=0;i<4;i++){
                block  = (GameObject)Instantiate(Block) as GameObject;
                block.gameObject.transform.position = new Vector2(-0.5f+i,4.5f);
                block.GetComponent<Renderer> ().material.color = colorList[random];
                movingBlock.Add(block);
            }
            rotationKey=1;
        }else if (random==1){//Oミノ
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    block  = (GameObject)Instantiate(Block) as GameObject;
                    block.gameObject.transform.position = new Vector2(-0.5f+i,4.5f-j);
                    block.GetComponent<Renderer> ().material.color = colorList[random];
                    movingBlock.Add(block);
                }
            }  
            rotationKey=3;
        }else if (random==2){//Sミノ
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    block  = (GameObject)Instantiate(Block) as GameObject;
                    block.gameObject.transform.position = new Vector2(-0.5f+i-j,4.5f-j);
                    block.GetComponent<Renderer> ().material.color = colorList[random];
                    movingBlock.Add(block);
                }           
            }
            rotationKey=3;
        }else if(random==3){//Zミノ
            for(int i=0;i<2;i++){
                for(int j=0;j<2;j++){
                    block  = (GameObject)Instantiate(Block) as GameObject;
                    block.gameObject.transform.position = new Vector2(-0.5f+i+j,4.5f-j);
                    block.GetComponent<Renderer> ().material.color = colorList[random];
                    movingBlock.Add(block);
                }           
            }   
            rotationKey=1;
        }else{//J,L,Tミノ
            //random4,5,6
            block  = (GameObject)Instantiate(Block) as GameObject;
            block.gameObject.transform.position = new Vector2(-0.5f+random-4,4.5f);                    
            block.GetComponent<Renderer> ().material.color = colorList[random];
            movingBlock.Add(block);
            for(int i=0;i<3;i++){
                block  = (GameObject)Instantiate(Block) as GameObject;
                block.gameObject.transform.position = new Vector2(-0.5f+i,3.5f);
                block.GetComponent<Renderer> ().material.color = colorList[random];
                movingBlock.Add(block);           
            }
            rotationKey=2;
        }
    }
    private bool check(string str){
        foreach(GameObject stock in movingBlock){
            int i=(int)(stock.gameObject.transform.position.x+4.5);
            int j=(int)(stock.gameObject.transform.position.y+4.5);
            if(str=="Right"){
                if(onOff[i+1,j]==1){
                    return false;
                }
            }
            else if(str=="Left"){
                if(onOff[i-1,j]==1){
                    return false;
                }
            }
            else if (str=="Down"){
                if(onOff[i,j-1]==1){
                    return false;
                }
            }
        }
        return true;
    }
    private bool checkRotation(string str){
        GameObject center = movingBlock[rotationKey];
        int centerX=(int)(center.gameObject.transform.position.x+4.5);
        int centerY=(int)(center.gameObject.transform.position.y+4.5);
        foreach(GameObject stock in movingBlock){
            int i=(int)(stock.gameObject.transform.position.x+4.5);
            int j=(int)(stock.gameObject.transform.position.y+4.5);
            if(str=="Right"){
                if(centerX-centerY+j<0|centerX-centerY+j>9|centerX+centerY-i<0|centerX+centerY-i>9){
                    return false;
                }
                if(onOff[centerX-centerY+j,centerX+centerY-i]==1){
                    return false;
                }
            }
            else if(str=="Left"){
                if(centerX+centerY-j<0|centerX+centerY-j>9|-centerX+centerY+i<0|-centerX+centerY+i>9){
                    return false;
                }
                if(onOff[centerX+centerY-j,-centerX+centerY+i]==1){
                    return false;
                }
            }
        }
        return true;
    }
    private void move(string str){
        foreach(GameObject stock in movingBlock){
            if(str=="Right"){
                stock.gameObject.transform.Translate(new Vector2(1,0));
            }
            else if(str=="Left"){
                stock.gameObject.transform.Translate(new Vector2(-1,0));
            }
            else if (str=="Down"){
                stock.gameObject.transform.Translate(new Vector2(0,-1));
            }
        }
    }
    private void rotate(string str){
        GameObject center = movingBlock[rotationKey];
        int centerX=(int)(center.gameObject.transform.position.x+4.5);
        int centerY=(int)(center.gameObject.transform.position.y+4.5);
        foreach(GameObject stock in movingBlock){
            int i=(int)(stock.gameObject.transform.position.x+4.5);
            int j=(int)(stock.gameObject.transform.position.y+4.5);
            if(str=="Right"){
                stock.gameObject.transform.position = new Vector2(-4.5f+centerX-centerY+j,-4.5f+centerX+centerY-i);
            }
            else if(str=="Left"){
                stock.gameObject.transform.position = new Vector2(-4.5f+centerX+centerY-j,-4.5f+-centerX+centerY+i);
            }
        }
    }
    private void changeToBackGround(){
        foreach(GameObject stock in movingBlock){
            int i=(int)(stock.gameObject.transform.position.x+4.5);
            int j=(int)(stock.gameObject.transform.position.y+4.5);
            onOff[i,j]=1;
            backGroundBlock  = (GameObject)Instantiate(backGround) as GameObject;
            backGroundBlock.gameObject.transform.position = new Vector2(-4.5f+i,-4.5f+j);
            backGroundBlock.GetComponent<Renderer> ().material.color = colorList[random];
            backGroundList[j][i]=backGroundBlock;
            Destroy(stock);
        }
        movingBlock.Clear();
    }
    private void checkLine(){
        int[] goodLine = new int[10]{1,0,0,0,0,0,0,0,0,0};
        for(int j=1;j<10;j++){
            int sum = 0;
            for(int i=1;i<9;i++){
                sum+=onOff[i,j];
            }
            if(sum==8){
                goodLine[j]=1;
            }
        }
        if(goodLine.Sum()>1){
            destroyLine(goodLine);
        }
    }
    private void destroyLine(int[] x){
        GameObject stock;
        int value = 1000;
        for(int j=1;j<10;j++){
            for(int i=1;i<9;i++){
                stock = backGroundList[j][i];
                backGroundList[j][i] = none;
                onOff[i,j]=0;
                if(x[j]==1){
                    Destroy(stock);
                    if(i==1){
                        score+=value;
                        value+=1000;
                        scoreText.text="Score: "+score.ToString();
                    }
                }else if (stock != none){
                    int downValue=-1;
                    for(int k=0;k<j;k++){
                        downValue+=x[k];
                    }
                    stock.gameObject.transform.Translate(new Vector2(0,-downValue));
                    backGroundList[j-downValue][i] = stock;
                    onOff[i,j-downValue]=1;
                }
            }
        }
    }


}

今後の課題

  • 下ボタンを押せるようにするとバグるので追加しなかった。
    =>そもそもの仕組みを変える必要があるかも?
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?