코딩/1-JavaScript

02_테트리스

tree0505 2025. 6. 10. 15:35
반응형
  • 그리드를 만들어서 . 그림을 그려서 꼼수로 할꺼다. 
  • 실제로는 움직이는 않는다.
  • 그리드를 만들어서 . 색칠하는거다.
  • 스네이크는 검사를 4군대만 하면 된다. 위 아래 왼쪽 오른쪽 
  • 테트리스 왼쪽은 3개. 아래는 3개. 오른쪽은 1개를 검사해야해서. 어렵다. 

  • 02_테트리스
  • _01_초기화

  • tetris01.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            .gray    { background-color: gray; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris01.js"></script>
    </body>
    </html>

  • tetris01.js
    let row      = 22;   // 세로 길이
    let col      = 12;   // 가로 길이
    //외각선을 줄려고 2를 더 한것
    //벽(gray)을 추가하기 위해 12칸을 설정한 것으로 보입니다.

    let dataList = [];   // 테트리스의 숫자구성
    //- 이 배열은 테트리스의 **게임 상태를 저장**하는 2차원 배열입니다.
    // - `dataList[i][j]` 형태로 각 셀에 접근할 수 있으며, 그 셀의 상태(빈칸인지, 벽인지, 블록인지 등)를 숫자로 저장합니다.
    //  - 예: `0`이면 빈칸, `8`이면 회색 벽, `1~7`은 블록 종류 등
    /*
        0000000000
        0000000000
        0000000000
        0000000000
        0000000000
        테트리스 표현
    */
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];
    //
    // 뜷린것 white
    //테트리스 색깔 : "green", "red", "purple", "orange", "blue", "yellow", "skyblue",
    //외각선 : gray
    //죽은 테트리스 : black

    // 자주 사용하는 값을 상수화
    const WHITE = 0; //뚫린것
    //- `WHITE`라는 이름으로 상수(변하지 않는 값) 선언
    // 의미: 빈칸(0)을 표현할 때 코드 가독성을 높이기 위해 `0` 대신 `WHITE`를 씁니다.
    const GRAY = 8; //외각선
    const BLACK = 9; //죽은 테트리스


    //✅ **요약**
    // 이 변수들과 상수는 테트리스 게임의 **보드 크기와 셀의 상태, 시각적 표현을 준비**하는 부분입니다.
    // dataList`는 전체 상태를 저장하고, `colorList`는 숫자 상태를 색으로 변환할 수 있게 도와줍니다.
    // `WHITE`, `GRAY`, `BLACK`은 숫자에 의미를 부여해서 코드 가독성을 높이는 역할입니다.

    //---------------------------------------------
    // 초기화
    // 게임을 시작할 때 테트리스 판을 만들고, 데이터를 초기 상태로 설정하는 역할을 합니다.
    function init() {

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");
        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) { //세로 방향으로 반복합니다. (총 22줄)
            let temp = []; //이 행에 해당하는 한 줄의 데이터를 저장할 배열을 만듭니다.
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) { //가로 방향으로 반복합니다. (총 12칸)
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
                //이 셀의 데이터 상태를 `0`으로 초기화하고 `temp` 배열에 저장합니다.
                //`0`은 빈칸을 의미합니다.
            }
            dataList.push(temp);
            // 완성된 한 줄의 데이터(`temp`)를 `dataList`에 추가합니다.
            // 결과적으로 `dataList`는 `2차원 배열`이 되며, 테트리스의 전체 상태를 담습니다.

            $myTetris.append($tr);
            //만들어진 <tr> 행을 테이블에 추가합니다.
        }
        $tetrisCenter.append($myTetris);
        //완성된 테이블을 실제 HTML 문서의 #tetrisCenter 영역에 추가하여 화면에 보이게 합니다.
       
        //-------------------------------------------------------
        // 첫 번째 for 반복문: 세로 벽(좌우 끝 줄)을 GRAY로 설정
        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        // 왼쪽 오른쪽 벽 회색
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY; //외각선 넣기
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        // 위 아래 벽
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }

    }

    init();

 


  • tetris02.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            /* 테트리스 색깔 */
            .gray    { background-color: gray; }
            .green   { background-color: green; }
            .red     { background-color: red; }
            .purple  { background-color: purple; }
            .orange  { background-color: orange; }
            .blue    { background-color: blue; }
            .yellow  { background-color: yellow; }
            .skyblue { background-color: skyblue; }
            .black   { background-color: black; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris02.js"></script>
    </body>
    </html>

  • tetris02.js
    let row = 22;   // 세로 길이
    let col = 12;   // 가로 길이
    let dataList = [];   // 테트리스의 숫자구성
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];

    // 자주 사용하는 값을 상수화
    // 상수 값이 변하지 않도록 고정된 변수 / 다시는 바꿀 수 없습니다.
    // if (data[i][j] === 0)    // ❌ 0이 무슨 의미인지 모름
    // if (data[i][j] === WHITE) // ✅ 흰색이라는 의미가 명확함
    // const => 변수 선언 할 때 사용하는거다. let과 마찬가지로. 하지만 변경이 불가
    const WHITE = 0;
    const GRAY = 8;
    const BLACK = 9;

    //현재위치
    let curY = 0;    // 처음 생성되는 블럭의 시작 y좌표
    let curX = 0;    // 처음 생성되는 블럭의 시작 x좌표

    let curBlock = null;   //현재 블럭  // 현재 블럭의 정보 저장

    let blockList = [ //블럭 종류
        {
            name: "s",
            color: 1, //인덱스.
            shape:
                [
                    [0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]
                ]
        },
        {
            name: "z",
            color: 2,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "t",
            color: 3,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 1],
                    [0, 1, 0]
                ]
        },
        {
            name: "l",
            color: 4,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "j",
            color: 5,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]
                ]
        },
        {
            name: "o",
            color: 6,
            shape:
                [
                    [1, 1],
                    [1, 1]
                ]
        },
        {
            name: "i",
            color: 7,
            shape:
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ]
        }
    ];
    //-------------------------------------------------------------------
    // 초기화
    function init() {

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");
        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) {
            let temp = [];
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) {
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
            }
            dataList.push(temp);
            $myTetris.append($tr);
        }
        $tetrisCenter.append($myTetris);

        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY;
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }

    }
    //------------------------------------------------------------------------
    // 랜덤으로 블럭 생성
    function setNewBlock() {

        //현재위치는 이것으로 고정한것
        //이것을 기준으로 9칸을 그린거다.
        curY = 1;
        curX = 4;

        let r = Math.floor(Math.random() * blockList.length);
        //let blockList 여기서 한개 뽑은것

        //r = 1;
        curBlock = blockList[r];    
        // 현재 블럭에 랜덤블럭 집어 넣기
        //이후 게임에서 이 블록을 움직이거나 회전할 때 사용함

        //그리기
        let shape = curBlock.shape;
        //.shape는 위의 객체의 shape이다. 즉 여러개의 블록의 shape
        // shape.length란?  shape에는 위의 2차원 배열이 들어가 있으므로
        //이 상태에서 shape.length를 출력하면 3입니다.👉 행(row)의 개수, 즉 세로 길이를 말해요.

        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    //그리기에서 1인것만 그린거다. //0일때는 색칠을 안함
                    // curY = 1;
                    // curX = 4;
                    // 1,4 , 1,5 , 2,4 , 2,5
                    // curY = 1
                    // 1 + 0 , 1 + 1
                    dataList[curY + y][curX + x] = blockList[r].color;
                    //dataList[  y][  x] = blockList[r].color;
                }
            }
        }
    }
    //-------------------------------------------------------------
    // 화면 새로 색칠하기
    // 그냥 화면 전체를 다 지우고. 다시 그리는것 // 코드를 쉽게 하기 위해서. //다시 색칠하는 것
    function draw() {
        let $myTetris = document.querySelector("#myTetris");

        for(let y=0; y<row; y++) {
            for(let x=0; x<col; x++) {
                let index = dataList[y][x];

                $myTetris.children[y].children[x].className = colorList[index];
                //myTetris => 테이블
                //children => tr
                // children => td
                //index에서 .gray 이걸 클래스.  => className
                $myTetris.children[y].children[x].innerText = dataList[y][x];
            }
        }
    }


    init();
    setNewBlock(); //새로운 블럭
    draw();

 


  • tetris03.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            .gray    { background-color: gray; }
            .green   { background-color: green; }
            .red     { background-color: red; }
            .purple  { background-color: purple; }
            .orange  { background-color: orange; }
            .blue    { background-color: blue; }
            .yellow  { background-color: yellow; }
            .skyblue { background-color: skyblue; }
            .black   { background-color: black; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris03.js"></script>
    </body>
    </html>

  • tetris03.js
  • let row = 22;   // 세로 길이
    let col = 12;   // 가로 길이
    let dataList = [];   // 테트리스의 숫자구성
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];

    // 자주 사용하는 값을 상수화
    const WHITE = 0;
    const GRAY = 8;
    const BLACK = 9;
    const BLOCK = GRAY;

    let curY = 0;    // 처음 생성되는 블럭의 시작 y좌표
    let curX = 0;    // 처음 생성되는 블럭의 시작 x좌표
    let curBlock = null;    // 현재 블럭의 정보 저장

    let blockList = [
        {
            name: "s",
            color: 1,
            shape:
                [
                    [0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]
                ]
        },
        {
            name: "z",
            color: 2,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "t",
            color: 3,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 1],
                    [0, 1, 0]
                ]
        },
        {
            name: "l",
            color: 4,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "j",
            color: 5,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]
                ]
        },
        {
            name: "o",
            color: 6,
            shape:
                [
                    [1, 1],
                    [1, 1]
                ]
        },
        {
            name: "i",
            color: 7,
            shape:
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ]
        }
    ];

    // 초기화 + 이벤트 등록
    function init() {

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");
        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) {
            let temp = [];
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) {
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
            }
            dataList.push(temp);
            $myTetris.append($tr);
        }
        $tetrisCenter.append($myTetris);

        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY;
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }
    //---------------------------------------------------------
        // 이벤트 등록
        // 이게 함수 밖에 있으면 widow인데 안에 있어서. document 이다.
        document.addEventListener("keydown", function(e) {
            if(e.code == "ArrowLeft") {
                // 왼쪽
                left(); //왼쪽으로 가고. 지우기
            } else if(e.code == "ArrowRight") {
                // 오른쪽
                right();
            } else if(e.code == "ArrowDown") {
                // 아래
                if(down() == false) { //false가 나오면 못 움직인다. / true가 나오면 움직임
                    setNewBlock(); //false가 나오면 새로운 블럭을 그리면 된다.
                }
            } else if(e.code == "ArrowUp") {
                // 회전
            } else if(e.code == "Space") {
                // 아래로 한번에 이동
                while(down()) {}

                setNewBlock(); // 다 내려가면 새로운 블럭
            }

            draw();
            //지우고 다시 그림
        });

    }

    // 랜덤으로 블럭 생성 + curBlock 초기화
    function setNewBlock() {

        curY = 1;
        curX = 4;

        let r = Math.floor(Math.random() * blockList.length);

        curBlock = blockList[r];
        let shape = curBlock.shape;
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    dataList[curY + y][curX + x] = blockList[r].color;
                }
            }
        }
    }

    // 화면 새로 색칠하기
    function draw() {
        let $myTetris = document.querySelector("#myTetris");

        for(let y=0; y<row; y++) {
            for(let x=0; x<col; x++) {
                let index = dataList[y][x];

                $myTetris.children[y].children[x].className = colorList[index];
                $myTetris.children[y].children[x].innerText = dataList[y][x];
            }
        }
    }
    //-------------------------------------------------------
    // 왼쪽 이동
    function left() {
        //미리 다음 위치
        let nextY = 0;
        let nextX = -1;

        let shape = curBlock.shape; //현재 블록
        let realBlock = getRealBlock(shape);
        // 실제 블럭이 있는 위치만 가져오기
        // 현재 블록에 리얼블록을 가져온다. //실제 블록의 위치만 가져온다.
        // 진짜 갈 수 있는지 없는지 판정이 됨
        // 만약 가져올때 0 과 1을 다 가져오면. 0때문에 이동을 못 할 수 있다.
        // getRealBlock => 모양에 1만 있는것

        let movable = isMovable(realBlock, nextY, nextX);
        //진짜 왼쪽으로 갈 수 있는지
        // nextY, nextX => 다음 위치를 넣어 준것

        if(movable == true) { //갈 수 있는것
            // dataList 값을 전부 WHITE로 변경

            setData(realBlock, 0, 0, WHITE);
            // 지운것 . 자기 위치 전부 지우기 / 현재위치 전부 지우기
            // dataLIST에 현재위치를 0,0을 넣어주는것
            // 이동 후의 위치로 dataList 값 변경
            // 아직까지는 데이터만 넣은것

            setData(realBlock, nextY, nextX, curBlock.color);
            //다음 위치 칠하기
           
            curX -= 1; //현재위치 수정
        }
    }
    //------------------------------------------------
    // 오른쪽 이동
    function right() {
        let nextY = 0;
        let nextX = 1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX += 1;
        }
    }
    //-------------------------------------------------
    // 아래로 이동
    function down() {
        let nextY = 1;
        let nextX = 0;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curY += 1;
        } else if(movable == false) {
            // 블럭이 바닥에 닿으면 //죽으면 검정으로 칠하기
            setData(realBlock, 0, 0, BLACK);
        }

        return movable;
    }
    //------------------------------------------
    // 실제 블럭이 있는 위치. 즉 1만 있는것 / 가져온것 위치만 가져오는것 . 위치 저장해서
    // block배열에서 숫자1의 값 저장
    function getRealBlock(shape) {
        let realBlock = [];
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    realBlock.push([curY + y, curX + x]);
                }
            }
        }
        return realBlock;
    }
    //----------------------------------------
    // 이동가능한지 확인
    function isMovable(realBlock, nextY, nextX) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            if(dataList[y + nextY][x + nextX] >= BLOCK) {
                return false;
                //BLOCK이면 갈 수 없다.
            }
        }
        return true; //블럭이 아니면 갈 수 있다.
    }

    // 이동 후 dataList 값 수정
    function setData(realBlock, nextY, nextX, color) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            dataList[y + nextY][x + nextX] = color;
        }
    }

    init();
    setNewBlock();
    draw();

_04_회전


  • tetris04.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            .gray    { background-color: gray; }
            .green   { background-color: green; }
            .red     { background-color: red; }
            .purple  { background-color: purple; }
            .orange  { background-color: orange; }
            .blue    { background-color: blue; }
            .yellow  { background-color: yellow; }
            .skyblue { background-color: skyblue; }
            .black   { background-color: black; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris04.js"></script>
    </body>
    </html>

  • tetris04.js
  • let row = 22;   // 세로 길이
    let col = 12;   // 가로 길이
    let dataList = [];   // 테트리스의 숫자구성
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];

    // 자주 사용하는 값을 상수화
    const WHITE = 0;
    const GRAY = 8;
    const BLACK = 9;
    const BLOCK = GRAY;

    let curY = 0;    // 처음 생성되는 블럭의 시작 y좌표
    let curX = 0;    // 처음 생성되는 블럭의 시작 x좌표
    let curBlock = null;    // 현재 블럭의 정보 저장

    let blockList = [
        {
            name: "s",
            color: 1,
            shape:
                [
                    [0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]
                ]
        },
        {
            name: "z",
            color: 2,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "t",
            color: 3,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 1],
                    [0, 1, 0]
                ]
        },
        {
            name: "l",
            color: 4,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "j",
            color: 5,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]
                ]
        },
        {
            name: "o",
            color: 6,
            shape:
                [
                    [1, 1],
                    [1, 1]
                ]
        },
        {
            name: "i",
            color: 7,
            shape:
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ]
        }
    ];

    // 초기화 + 이벤트 등록
    function init() {

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");
        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) {
            let temp = [];
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) {
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
            }
            dataList.push(temp);
            $myTetris.append($tr);
        }
        $tetrisCenter.append($myTetris);

        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY;
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }

        // 이벤트 등록
        document.addEventListener("keydown", function(e) {
            if(e.code == "ArrowLeft") {
                // 왼쪽
                left();
            } else if(e.code == "ArrowRight") {
                // 오른쪽
                right();
            } else if(e.code == "ArrowDown") {
                // 아래
                if(down() == false) {
                    setNewBlock();
                }
            } else if(e.code == "ArrowUp") {
                // 회전~~~~~~~~~
                rotate();
            } else if(e.code == "Space") {
                // 아래로 한번에 이동
                while(down()) {}

                setNewBlock();
            }

            draw();
        });

    }

    // 랜덤으로 블럭 생성 + curBlock 초기화
    function setNewBlock() {

        curY = 1;
        curX = 4;

        let r = Math.floor(Math.random() * blockList.length);

        curBlock = blockList[r];
        let shape = curBlock.shape;
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    dataList[curY + y][curX + x] = blockList[r].color;
                }
            }
        }
    }

    // 화면 새로 색칠하기
    function draw() {
        let $myTetris = document.querySelector("#myTetris");

        for(let y=0; y<row; y++) {
            for(let x=0; x<col; x++) {
                let index = dataList[y][x];

                $myTetris.children[y].children[x].className = colorList[index];
                $myTetris.children[y].children[x].innerText = dataList[y][x];
            }
        }
    }

    // 왼쪽 이동
    function left() {
        let nextY = 0;
        let nextX = -1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX -= 1;
        }
    }

    // 오른쪽 이동
    function right() {
        let nextY = 0;
        let nextX = 1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX += 1;
        }
    }

    // 아래로 이동
    function down() {
        let nextY = 1;
        let nextX = 0;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curY += 1;
        } else if(movable == false) {
            // 블럭이 바닥에 닿으면
            setData(realBlock, 0, 0, BLACK);
        }

        return movable;
    }
    //----------------------------------------------------
    // 회전
    function rotate() {
        let curShape = curBlock.shape;
        let nextShape = getNextShape(curShape);
        // curShape => 현재블록
        // 현재블럭에 다음 모양을 가져오는 함수
        // nextShape => 회전후 모양

        let realBlock = getRealBlock(curShape);
        // 현재 모양의 진짜 블럭 위치

        let nextRealBlock = getRealBlock(nextShape);
        //회전한 모양의 진짜 블럭위치

        let movable = isMovable(nextRealBlock, 0, 0);
        //회전이 가능하니??

        if(movable) {
            setData(realBlock, 0, 0, WHITE);
            //현재위치 지우고

            setData(nextRealBlock, 0, 0, curBlock.color);
            //새위치 그리고
            curBlock.shape = nextShape;
            //회전시키는것
            //현재블럭을 회전한 블럭으로 대체
        }
    }
    //--------------------------------------------
    // 회전 상태의 모양
    function getNextShape(curShape) {
        let tempBlock = [];
        for(let i=0; i<curShape.length; i++) {
            let temp = [];
            for(let j=0; j<curShape[i].length; j++) {
                temp.push(0);
            }
            tempBlock.push(temp);
        }

        let index = curShape.length - 1;
        for(let y=0; y<curShape.length; y++) {
            for(let x=0; x<curShape[y].length; x++) {
                tempBlock[x][index] = curShape[y][x];
            }
            index -= 1;
        }

        return tempBlock;
    }

    // block배열에서 숫자1의 값 저장
    function getRealBlock(shape) {
        let realBlock = [];
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    realBlock.push([curY + y, curX + x]);
                }
            }
        }
        return realBlock;
    }

    // 이동가능한지 확인
    function isMovable(realBlock, nextY, nextX) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            if(dataList[y + nextY][x + nextX] >= BLOCK) {
                return false;
            }
        }
        return true;
    }

    // 이동 후 dataList 값 수정
    function setData(realBlock, nextY, nextX, color) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            dataList[y + nextY][x + nextX] = color;
        }
    }

    init();
    setNewBlock();
    draw();

_05_삭제


  • tetris05.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            .gray    { background-color: gray; }
            .green   { background-color: green; }
            .red     { background-color: red; }
            .purple  { background-color: purple; }
            .orange  { background-color: orange; }
            .blue    { background-color: blue; }
            .yellow  { background-color: yellow; }
            .skyblue { background-color: skyblue; }
            .black   { background-color: black; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris05.js"></script>
    </body>
    </html>

  • tetris05.js
  • let row = 22;   // 세로 길이
    let col = 12;   // 가로 길이
    let dataList = [];   // 테트리스의 숫자구성
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];

    // 자주 사용하는 값을 상수화
    const WHITE = 0;
    const GRAY = 8;
    const BLACK = 9;
    const BLOCK = GRAY;

    let curY = 0;    // 처음 생성되는 블럭의 시작 y좌표
    let curX = 0;    // 처음 생성되는 블럭의 시작 x좌표
    let curBlock = null;    // 현재 블럭의 정보 저장

    let blockList = [
        {
            name: "s",
            color: 1,
            shape:
                [
                    [0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]
                ]
        },
        {
            name: "z",
            color: 2,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "t",
            color: 3,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 1],
                    [0, 1, 0]
                ]
        },
        {
            name: "l",
            color: 4,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "j",
            color: 5,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]
                ]
        },
        {
            name: "o",
            color: 6,
            shape:
                [
                    [1, 1],
                    [1, 1]
                ]
        },
        {
            name: "i",
            color: 7,
            shape:
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ]
        }
    ];

    // 초기화 + 이벤트 등록
    function init() {

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");
        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) {
            let temp = [];
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) {
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
            }
            dataList.push(temp);
            $myTetris.append($tr);
        }
        $tetrisCenter.append($myTetris);

        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY;
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }

        // 이벤트 등록
        document.addEventListener("keydown", function(e) {
            if(e.code == "ArrowLeft") {
                // 왼쪽
                left();
            } else if(e.code == "ArrowRight") {
                // 오른쪽
                right();
            } else if(e.code == "ArrowDown") {
                // 아래
                if(down() == false) {
                    lineClear();
                    setNewBlock();
                }
            } else if(e.code == "ArrowUp") {
                // 회전
                rotate();
            } else if(e.code == "Space") {
                // 아래로 한번에 이동
                while(down()) {}

                lineClear();
                setNewBlock();
            }

            draw();
        });

    }

    // 랜덤으로 블럭 생성 + curBlock 초기화
    function setNewBlock() {

        curY = 1;
        curX = 4;

        let r = Math.floor(Math.random() * blockList.length);

        curBlock = blockList[r];
        let shape = curBlock.shape;
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    dataList[curY + y][curX + x] = blockList[r].color;
                }
            }
        }
    }

    // 화면 새로 색칠하기
    function draw() {
        let $myTetris = document.querySelector("#myTetris");

        for(let y=0; y<row; y++) {
            for(let x=0; x<col; x++) {
                let index = dataList[y][x];

                $myTetris.children[y].children[x].className = colorList[index];
                $myTetris.children[y].children[x].innerText = dataList[y][x];
            }
        }
    }

    // 왼쪽 이동
    function left() {
        let nextY = 0;
        let nextX = -1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX -= 1;
        }
    }

    // 오른쪽 이동
    function right() {
        let nextY = 0;
        let nextX = 1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX += 1;
        }
    }

    // 아래로 이동
    function down() {
        let nextY = 1;
        let nextX = 0;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curY += 1;
        } else if(movable == false) {
            // 블럭이 바닥에 닿으면
            setData(realBlock, 0, 0, BLACK);
        }

        return movable;
    }

    // 회전
    function rotate() {
        let curShape = curBlock.shape;
        let nextShape = getNextShape(curShape);

        let realBlock = getRealBlock(curShape);
        let nextRealBlock = getRealBlock(nextShape);
        let movable = isMovable(nextRealBlock, 0, 0);

        if(movable) {
            setData(realBlock, 0, 0, WHITE);

            setData(nextRealBlock, 0, 0, curBlock.color);
            curBlock.shape = nextShape;
        }
    }

    // 회전 상태의 모양
    function getNextShape(curShape) {
        let tempBlock = [];
        for(let i=0; i<curShape.length; i++) {
            let temp = [];
            for(let j=0; j<curShape[i].length; j++) {
                temp.push(0);
            }
            tempBlock.push(temp);
        }

        let index = curShape.length - 1;
        for(let y=0; y<curShape.length; y++) {
            for(let x=0; x<curShape[y].length; x++) {
                tempBlock[x][index] = curShape[y][x];
            }
            index -= 1;
        }

        return tempBlock;
    }

    // block배열에서 숫자1의 값 저장
    function getRealBlock(shape) {
        let realBlock = [];
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    realBlock.push([curY + y, curX + x]);
                }
            }
        }
        return realBlock;
    }

    // 이동가능한지 확인
    function isMovable(realBlock, nextY, nextX) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            if(dataList[y + nextY][x + nextX] >= BLOCK) {
                return false;
            }
        }
        return true;
    }

    // 이동 후 dataList 값 수정
    function setData(realBlock, nextY, nextX, color) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            dataList[y + nextY][x + nextX] = color;
        }
    }
    //--------------------------------------------
    // 한 줄 완성되면 삭제
    function lineClear() {
        let del = [];
        for(let y=1; y<row-1; y++) {
            let count = 0;
            for(let x=1; x<col-1; x++) {
                if(dataList[y][x] == BLACK) {
                    count += 1;
                }
            }
            if(count == 10) {
                del.push(y);
            }
        }
        //한줄 다 됬는지
        //----------------------------
        //카운트가 10개면
        for(let i=0; i<del.length; i++) {

            dataList.splice(del[i], 1);
            dataList.splice(0, 1);
            //지우고

            //붙여넣고 / 지운만큼 다시 그려 넣은것
            dataList.unshift([BLOCK,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,BLOCK]);
            dataList.unshift([BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK]);
        }
       
    }

    init();
    setNewBlock();
    draw();

  • _06_게임플레이어
  • 다운을 1초마다 한것 

  • tetris06.html
  • <!DOCTYPE html>
    <html lang="ko">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Tetris Game</title>

        <style>
            #center {
                margin: 0 auto;
                text-align: center;
            }
            #myTetris {
                border-collapse: collapse;
            }
            #myTetris td {
                border: 1px solid black;
                width: 30px;
                height: 30px;
            }
            .gray    { background-color: gray; }
            .green   { background-color: green; }
            .red     { background-color: red; }
            .purple  { background-color: purple; }
            .orange  { background-color: orange; }
            .blue    { background-color: blue; }
            .yellow  { background-color: yellow; }
            .skyblue { background-color: skyblue; }
            .black   { background-color: black; }
        </style>

    </head>
    <body>
        <table id="center">
            <tr>
                <td>
                    <h1>테트리스</h1>
                </td>
            </tr>
            <tr>
                <td id="tetrisCenter"></td>
            </tr>
        </table>

        <script src="tetris06.js"></script>
    </body>
    </html>

  • tetris06.js
  • let row = 22;   // 세로 길이
    let col = 12;   // 가로 길이
    let dataList = [];   // 테트리스의 숫자구성
    let colorList = ["white", "green", "red", "purple", "orange", "blue", "yellow", "skyblue", "gray", "black"];

    // 자주 사용하는 값을 상수화
    const WHITE = 0;
    const GRAY = 8;
    const BLACK = 9;
    const BLOCK = GRAY;

    let curY = 0;    // 처음 생성되는 블럭의 시작 y좌표
    let curX = 0;    // 처음 생성되는 블럭의 시작 x좌표
    let curBlock = null;    // 현재 블럭의 정보 저장

    let gameOver = false;
    let intervalId = null;

    let blockList = [
        {
            name: "s",
            color: 1,
            shape:
                [
                    [0, 0, 0],
                    [0, 1, 1],
                    [1, 1, 0]
                ]
        },
        {
            name: "z",
            color: 2,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "t",
            color: 3,
            shape:
                [
                    [0, 0, 0],
                    [1, 1, 1],
                    [0, 1, 0]
                ]
        },
        {
            name: "l",
            color: 4,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [0, 1, 1]
                ]
        },
        {
            name: "j",
            color: 5,
            shape:
                [
                    [0, 1, 0],
                    [0, 1, 0],
                    [1, 1, 0]
                ]
        },
        {
            name: "o",
            color: 6,
            shape:
                [
                    [1, 1],
                    [1, 1]
                ]
        },
        {
            name: "i",
            color: 7,
            shape:
                [
                    [0, 0, 0, 0],
                    [1, 1, 1, 1],
                    [0, 0, 0, 0],
                    [0, 0, 0, 0],
                ]
        }
    ];

    // 초기화 + 이벤트 등록
    function init() {

        dataList = [];
        curY = 0;
        curX = 0;
        curBlock = null;
        gameOver = false;
        intervalId = null;

        if(document.querySelector("#myTetris") != null) {
            document.querySelector("#myTetris").remove();
        }

        // 테트리스 표 그리기, dataList 0으로 채우기
        let $tetrisCenter = document.querySelector("#tetrisCenter");
        let $myTetris = document.createElement("table");

        $myTetris.id = "myTetris";
        for(let i=0; i<row; i++) {
            let temp = [];
            let $tr = document.createElement("tr");
            for(let j=0; j<col; j++) {
                let $td = document.createElement("td");
                $tr.append($td);
                temp.push(0);
            }
            dataList.push(temp);
            $myTetris.append($tr);
        }
        $tetrisCenter.append($myTetris);

        // 테트리스 세로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<row; i++) {
            dataList[i][0] = GRAY;
            dataList[i][col - 1] = GRAY;

            $myTetris.children[i].children[0].className = colorList[GRAY];
            $myTetris.children[i].children[col-1].className = colorList[GRAY];
        }

        // 테트리스 가로 8(gray)으로 채우기 + class이름을 gray로 설정
        for(let i=0; i<col; i++) {
            dataList[0][i] = GRAY;
            dataList[row - 1][i] = GRAY;

            $myTetris.children[0].children[i].className = colorList[GRAY];
            $myTetris.children[row - 1].children[i].className = colorList[GRAY];
        }

        // dataList 화면에 표시하기
        for(let i=0; i<row; i++) {
            for(let j=0; j<col; j++) {
                $myTetris.children[i].children[j].innerText = dataList[i][j];
            }
        }

        intervalId = setInterval(playGame, 500);
        //다운을 1초마다 하면 된다. //움직이는 테트리스
        //다운을 setInterval에다가 넣으면 된다.
       
    }

    // 랜덤으로 블럭 생성 + curBlock 초기화 + 게임종료 확인
    function setNewBlock() {

        curY = 1;
        curX = 4;

        let r = Math.floor(Math.random() * blockList.length);

        curBlock = blockList[r];
        let shape = curBlock.shape;

        // 게임 종료여부 확인
        isGameOver();

        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    dataList[curY + y][curX + x] = blockList[r].color;
                }
            }
        }
    }

    // 화면 새로 색칠하기
    function draw() {
        let $myTetris = document.querySelector("#myTetris");

        for(let y=0; y<row; y++) {
            for(let x=0; x<col; x++) {
                let index = dataList[y][x];

                $myTetris.children[y].children[x].className = colorList[index];
                $myTetris.children[y].children[x].innerText = dataList[y][x];
            }
        }
    }

    // 왼쪽 이동
    function left() {
        let nextY = 0;
        let nextX = -1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX -= 1;
        }
    }

    // 오른쪽 이동
    function right() {
        let nextY = 0;
        let nextX = 1;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curX += 1;
        }
    }

    // 아래로 이동
    function down() {
        let nextY = 1;
        let nextX = 0;

        let shape = curBlock.shape;
        let realBlock = getRealBlock(shape);
        let movable = isMovable(realBlock, nextY, nextX);

        if(movable == true) {
            // dataList 값을 전부 WHITE로 변경
            setData(realBlock, 0, 0, WHITE);
            // 이동 후의 위치로 dataList 값 변경
            setData(realBlock, nextY, nextX, curBlock.color);
           
            curY += 1;
        } else if(movable == false) {
            // 블럭이 바닥에 닿으면
            setData(realBlock, 0, 0, BLACK);
        }

        return movable;
    }

    // 회전
    function rotate() {
        let curShape = curBlock.shape;
        let nextShape = getNextShape(curShape);

        let realBlock = getRealBlock(curShape);
        let nextRealBlock = getRealBlock(nextShape);
        let movable = isMovable(nextRealBlock, 0, 0);

        if(movable) {
            setData(realBlock, 0, 0, WHITE);

            setData(nextRealBlock, 0, 0, curBlock.color);
            curBlock.shape = nextShape;
        }
    }

    // 회전 상태의 모양
    function getNextShape(curShape) {
        let tempBlock = [];
        for(let i=0; i<curShape.length; i++) {
            let temp = [];
            for(let j=0; j<curShape[i].length; j++) {
                temp.push(0);
            }
            tempBlock.push(temp);
        }

        let index = curShape.length - 1;
        for(let y=0; y<curShape.length; y++) {
            for(let x=0; x<curShape[y].length; x++) {
                tempBlock[x][index] = curShape[y][x];
            }
            index -= 1;
        }

        return tempBlock;
    }

    // block배열에서 숫자1의 값 저장
    function getRealBlock(shape) {
        let realBlock = [];
        for(let y=0; y<shape.length; y++) {
            for(let x=0; x<shape[y].length; x++) {
                if(shape[y][x] == 1) {
                    realBlock.push([curY + y, curX + x]);
                }
            }
        }
        return realBlock;
    }

    // 이동가능한지 확인
    function isMovable(realBlock, nextY, nextX) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            if(dataList[y + nextY][x + nextX] >= BLOCK) {
                return false;
            }
        }
        return true;
    }

    // 이동 후 dataList 값 수정
    function setData(realBlock, nextY, nextX, color) {
        for(let i=0; i<realBlock.length; i++) {
            let y = realBlock[i][0];
            let x = realBlock[i][1];

            dataList[y + nextY][x + nextX] = color;
        }
    }

    // 한 줄 완성되면 삭제
    function lineClear() {
        let del = [];
        for(let y=1; y<row-1; y++) {
            let count = 0;
            for(let x=1; x<col-1; x++) {
                if(dataList[y][x] == BLACK) {
                    count += 1;
                }
            }
            if(count == 10) {
                del.push(y);
            }
        }

        for(let i=0; i<del.length; i++) {
            dataList.splice(del[i], 1);
            dataList.splice(0, 1);

            dataList.unshift([BLOCK,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,WHITE,BLOCK]);
            dataList.unshift([BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK,BLOCK]);
        }
    }

    // 게임 시작
    function playGame() {
        if(gameOver == true) {
            clearInterval(intervalId);

            alert("게임종료!");
            init();
            setNewBlock();
            draw();

            return;
        }

        if(down() == false) {
            lineClear();
            setNewBlock();
        }
        draw();
    }

    // 게임 종료
    // 게임 오버됬는지 확인하는것
    function isGameOver() {
        let realBlock = getRealBlock(curBlock.shape);

        for(let y=0; y<realBlock.length; y++) {
            if(dataList[realBlock[y][0]][realBlock[y][1]] == BLACK) {
                gameOver = true;
                break;
            }
        }

        console.log(gameOver);
    }

    // 이벤트 등록
    document.addEventListener("keydown", function(e) {
        if(e.code == "ArrowLeft") {
            // 왼쪽
            left();
        } else if(e.code == "ArrowRight") {
            // 오른쪽
            right();
        } else if(e.code == "ArrowDown") {
            // 아래
            if(down() == false) {
                lineClear();
                setNewBlock();
            }
        } else if(e.code == "ArrowUp") {
            // 회전
            rotate();
        } else if(e.code == "Space") {
            // 아래로 한번에 이동
            while(down()) {}

            lineClear();
            setNewBlock();
        }

        draw();
    });


    init();
    setNewBlock();
    draw();
반응형