본문 바로가기
Project/테트리스

[테트리스] 5. 다음블럭출력, 한 줄 삭제

by 햄과함께 2019. 8. 27.
320x100

2018. 7. 28.


# 다음 블럭 출력

// 캔버스 추가
var canvasNextBlock = document.getElementById("nextBlock");
var ctxNextBlock = canvasNextBlock.getContext("2d");

var drawNextBlock = function() {
    var nextBlock = blockType[nextBlockType];
    var x = 0;
    var y = 0;
    for (var i = 0; i < SMALL_BLOCK_NUM; i++) {
        for (var j = 0; j < SMALL_BLOCK_NUM; j++) {
            //블럭 있는 칸은 해당 색으로
            if (nextBlock.shape[i][j] == 1) {
                ctxNextBlock.fillStyle = nextBlock.color;
            } else { //없는 곳은 흰색으로
                ctxNextBlock.fillStyle = "white";
            }
            ctxNextBlock.fillRect(
                (x + j) * SMALL_BLOCK_SIZE,
                (y + i) * SMALL_BLOCK_SIZE,
                SMALL_BLOCK_SIZE,
                SMALL_BLOCK_SIZE
            );
        }
    }
};
# 한 줄 삭제

// sy ~ se row에서 지워질 수 있는 행 체크 & 지우기
var checkRowsAndErase = function(sy, ey) {
    var isEraseAnything = false;
    for (var i = sy; i <= ey; i++) {
        if (canEraseRow(i)) { // 한 줄 삭제 가능하면
            eraseRow(i); //해당 줄 삭제
            isEraseAnything = true; 
        }
    }
    if (isEraseAnything) {//삭제 한 행이 있으면
        rearrange(); //재배열
    }
};

//한 줄 삭제 가능한가
var canEraseRow = function(row) {
    for (var j = 0; j < GAME_SCREEN_WIDTH_NUM; j++) {
        if (gameScreenArray[row][j] == -1) { //빈 칸이 하나라도 있으면
            return false; //삭제 불가능
        }
    }
    return true;
};

// 한 줄 삭제
var eraseRow = function(row) {
    for (var j = 0; j < GAME_SCREEN_WIDTH_NUM; j++) {
        eraseOneBlock(row, j);
        gameScreenArray[row][j] = NOW_DELETE; //삭제된 행이라고 명시
    }
};

//한 칸 삭제
var eraseOneBlock = function(x, y) {
    ctx.clearRect(
        y * SMALL_BLOCK_SIZE,
        x * SMALL_BLOCK_SIZE,
        SMALL_BLOCK_SIZE,
        SMALL_BLOCK_SIZE
    );
    gameScreenArray[x][y] = -1;
};

//한 칸 그리기
var drawOneBlock = function(x, y, colorType) {
    ctx.fillStyle = blockType[colorType].color;
    ctx.fillRect(
        y * SMALL_BLOCK_SIZE,
        x * SMALL_BLOCK_SIZE,
        SMALL_BLOCK_SIZE,
        SMALL_BLOCK_SIZE
    );
    gameScreenArray[x][y] = colorType;
};

// 삭제된 행이 있으면 그 위에 블럭들이 한 칸 내려와야 함 -> 재배열
var rearrange = function() {
    for (var j = 0; j < GAME_SCREEN_WIDTH_NUM; j++) {
        // from bottom
        var deleteBlockNum = 0; //삭제된 칸 수
        for (var i = GAME_SCREEN_HEIGHT_NUM - 1; i >= 0; i--) {
            if (gameScreenArray[i][j] == -1) continue; // 원래 빈 칸
            if (gameScreenArray[i][j] == NOW_DELETE) { //삭제된 칸
                gameScreenArray[i][j] = -1; //빈 칸으로 변경
                eraseOneBlock(i, j); //한 칸 삭제
                deleteBlockNum++; 
            } else {
                var blockColor = gameScreenArray[i][j];
                console.log(blockColor);
                eraseOneBlock(i, j); // 현재 칸 삭제
                // 삭제된 칸 만큼 아래로 이동해서 그려줌
                drawOneBlock(i + deleteBlockNum, j, blockColor);
            }
        }
    }
};

한 줄 삭제 후 기존에 있던 블럭들을 한 칸 내린 상태로 그려주기 위해 게임판 배열에 저장하는 값을 바꿨다.
기존에는 있고 없고만을 저장하기만 하면됐으므로 0(없음), 1(있음)을 저장하였고.
이번에는 블럭 배열의 타입 인덱스를 저장했다.
블럭 삭제 후 블럭들의 새로운 위치에 그려줄 때 해당 배열에 저장된 type 인덱스 값을 보고 적절한 색으로 다시 그려준다.

개발 순서를 잘못 설정한 듯 하다.
블럭 모양 변경을 먼저 했어야 했는데... 모양 변경안되니까 한 줄 맞추기 어렵

한 줄 삭제

 

왼쪽 상단에 다음 블럭 출력


깃허브
draw what is next Block
one row delete

320x100

댓글