코딩 강의/컨텐츠를 만들어 볼까요

테트리스 게임 개발 #2 - 블럭 모양 및 랜덤 선택 구현

아미넴 2020. 9. 12.
반응형

목차

     

    지난 강의 리뷰

    테트리스 게임 개발 #1 - HTML, 자바스크립트, CSS를 활용하여 기본 화면 구성

     

    테트리스 게임 개발 #1 - HTML, 자바스크립트, CSS를 활용하여 기본 화면 구성

    게임 개발 하면 제일 먼저 떠 오르는 종류가 보드 게임, 그 중에서도 테트리스가 아닌가 싶어요. 게다가 최근 웹 언어가 활용도가 높고 그 만큼 관심이 커지고 있기 때문에 지금부터 순수 HTML, Ja

    sangminem.tistory.com

     

    지난 포스팅에서는 테트리스 게임을 만들기 위해

    아래와 같이 기본적인 틀만 간단히 구현해 보았는데요.

     

    1. 지금부터는 main-board와 next-board에 특정 블럭을 선택하고

    2. 선택된 블럭을 그려 볼게요.

     

    블럭 모양 구성

    테트리스 게임에서는 아래와 같이 블럭의 모양을 정사각형 4개를 활용하여 7가지 형태로 만듭니다.

    위와 같은 모양을 배열 형태로 생각해 보겠습니다.

    const BLOCK_SET = [
        [
            [1,1],
            [1,1]
        ],
        [
            [0,2,0],
            [2,2,2],
            [0,0,0]
        ],
        [
            [0,3,3],
            [3,3,0],
            [0,0,0]
        ],
        [
            [4,4,0],
            [0,4,4],
            [0,0,0]
        ],
        [
            [5,0,0],
            [5,5,5],
            [0,0,0]
        ],
        [
            [0,0,6],
            [6,6,6],
            [0,0,0]
        ],
        [
            [0,0,0,0],
            [7,7,7,7],
            [0,0,0,0],
            [0,0,0,0]
        ]
    ]

    위와 같이 초기 포지션을 고려하여 7가지 모양을 배열로 담았습니다.

    블럭을 회전했을 때의 영역까지 고려하여 행과 열의 갯수를 동일하게 맞추었구요.

    각 블럭의 모양별로 배열의 숫자 값을 다르게 하여 구분이 가능하게 하였습니다.

    0은 당연히 빈 공간을 의미합니다.

     

     

    블럭 선택 기능 구현

    그 다음 블럭 모양을 무작위로 가져와야 하므로 랜덤 함수도 하나 만들어 보겠습니다.

    function getRandomIndex(length) {
        return Math.floor(Math.random()*length);
    }

    간단하게 배열의 길이를 인자로 받아 0~(배열 길이-1)을 리턴하는 함수를 만들었습니다.

    따라서 블럭 배열의 길이를 인자로 전달하면 0~6 값을 가져 옵니다.

     

    이어서 무작위 블럭 선택 함수를 만듭니다.

    function randomNextBlockMatrix() {
        //... BLOCK_SET 배열 생략
        return BLOCK_SET[getRandomIndex(BLOCK_SET.length)];
    }

    간단하게 랜덤 함수를 이용하여 7가지 모양 중 하나를 선택하도록 하였습니다.

     

    그럼 위에서 만든 함수를 이용하여

    main-board에 표시할 블럭과 next-board에 표시할 블럭을 변수에 하나씩 담아 보겠습니다.

    //... 기존 선언 변수 생략
    let mainBlock = null;
    let nextBlock = null;
    
    function main() {
        mainBlock = createNextBlock();
        nextBlock = createNextBlock();
        //... 기존 로직 생략
    }
    
    function createNextBlock() {
        const nextBlock = {
            x: 0,
            y: 0,
            shape: randomNextBlockMatrix()
        }
    
        return nextBlock;
    }

    먼저 글로벌 변수로 mainBlock, nextBlock 변수를 선언했습니다.

    그리고 x, y 좌표 값과 블럭 모양의 배열 값을 갖는 JSON 형태 오브젝트를 리턴하는 함수를 만들어서

    main 함수에서 각 변수에 할당했습니다.

    main-board에 mainBlock을 쌓으면 다시 mainBlock에 nextBlock을 할당하는 방식으로 구현 예정입니다.

     

    화면에 그리기

    이렇게 변수에 할당만 한다고 실제 canvas에는 그려지지 않습니다.

    이제 선택된 블럭을 그리는 함수를 작성해 보겠습니다.

    function rebuild() {
        resize();
        drawBlock(mainBlock, ctxMainBoard);
        drawBlock(nextBlock, ctxNextBoard);
    }
    
    function drawBlock(block, ctx) {
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
    
        block.shape.forEach((row, y) => {
            row.forEach((value, x) => {
                if(value > 0) {
                    ctx.fillStyle = 'white';
                    ctx.fillRect(x + block.x, y + block.y, 1, 1);
                }
            });
        });
    }

    block과 canvas context를 인자로 받는 함수를 하나 만들었습니다.

    최초에 board를 싹 클리어 하고

    block 모양에 따른 배열 index와 블럭의 위치를 고려하여

    board에 흰색의 사각형으로 블럭을 그리는 로직입니다.

     

    그리고 rebuild 함수에 resize 함수를 포함 시키고

    각각의 블럭과 canvas context를 인자로 받아 그리도록 drawBlock 함수를 호출 하였습니다.

    그에 따라 main 함수에서 호출한 resize 함수를 rebuild 함수로 교체해 주겠습니다.

     

     

    결과 보기

    여기까지 저장을 하고 한 번 실행해 보겠습니다.

    초기 위치를 아직 설정하지 않아 맨 상단 좌측에 표시되긴 했지만

    원하는 대로 블럭이 잘 표현된 것을 볼 수 있습니다.

     

    점점 게임의 요소가 갖춰지고 있습니다.

    내 손으로 게임을 만들 수 있다니 재밌지 않나요. :)

     

    다음 포스팅에서는 main-board의 블럭을

    키보드 방향키로 움직여 보도록 하겠습니다.

     

    기대해 주세요!

     

    #다음강의

    테트리스 게임 개발 #3 - 블럭 이동 기능 구현

     

    테트리스 게임 개발 #3 - 블럭 이동 기능 구현

    목차 지난 강의 리뷰 테트리스 게임 개발 #2 - 블럭 모양 및 랜덤 선택 구현 테트리스 게임 개발 #2 - 블럭 모양 및 랜덤 선택 구현 목차 지난 강의 리뷰 테트리스 게임 개발 #1 - 소개 및 기본 화면

    sangminem.tistory.com

     

    반응형

    댓글

    💲 추천 글