본문 바로가기

javaScript

JavaScript 테트리스 만들기 - 4

728x90

2024.04.02 - [javaScript] - JavaScript 테트리스 만들기 - 1

 

JavaScript 테트리스 만들기 - 1

요즘 개발 트렌드는 javaScript를 편하게 사용하도록 도와주는 라이브러리를 활용한 개발이 아닌 순수(바닐라) javaScript를 이용한 개발이라고 어디에선가 들은 적이 있다. javaScript의 꾸준히 업데이

son33.tistory.com

2024.04.02 - [javaScript] - JavaScript 테트리스 만들기 - 2

 

JavaScript 테트리스 만들기 - 2

2024.04.02 - [javaScript] - JavaScript 테트리스 만들기 - 1 JavaScript 테트리스 만들기 - 1 요즘 개발 트렌드는 javaScript를 편하게 사용하도록 도와주는 라이브러리를 활용한 개발이 아닌 순수(바닐라) javaScri

son33.tistory.com

2024.04.04 - [javaScript] - JavaScript 테트리스 만들기 - 3

 

JavaScript 테트리스 만들기 - 3

2024.04.02 - [javaScript] - JavaScript 테트리스 만들기 - 1 JavaScript 테트리스 만들기 - 1 요즘 개발 트렌드는 javaScript를 편하게 사용하도록 도와주는 라이브러리를 활용한 개발이 아닌 순수(바닐라) javaScri

son33.tistory.com

 

1. 블록 한 번에 내리기

// 블록 맨 아래로 내리기
function dropBlock(nowBlock){
    if(!collisionBlock(nowBlock, 0)){
        let startX = parseInt(nowBlock[0].classList[0].replace("col",""));
        let startY = parseInt(nowBlock[0].classList[1].replace("row",""));
        let shape = blockShape(nowBlock);
        deleteBlock(nowBlock);
        nowBlock = drawBlock(startX, startY + 1, shape);
        return dropBlock(nowBlock);
    } else {
        fixBlock(nowBlock);
        deleteRow(nowBlock);
        return createBlock();
    }
}

우선 keyCode가 32번이면 dropBlock()을 호출시킨다. dropBLock의 코드는 다음과 같다.

1) 미충돌 시

먼저 받아온 nowBlock을 collisionBlock()으로 보내어 충돌여부를 확인하고 충돌하지 않으면 deleteBlock과 nowBlock을 순차적으로 호출해 블록을 한 칸 내린 뒤 충돌이 발생할 때까지 dropBlock을 호출시킨다.

2) 충돌 시

반대로 충돌이 일어나지 않으면 지금 블록은 fixBkock을 호출해 고정시키고 deleteRow를 호출해 줄 삭제여부를 확인한 뒤 createBlock을 호출해 새로운 블록이 생성되도록 한다.

2. 줄 지우기

// 행 삭제 및 블록 아래로 이동
function deleteRow(nowBlock) {
    nowBlock.forEach(block => {
        let row = parseInt(block.classList[1].replace("row", ""));
        // 각 행마다 fixed-block의 개수를 세어 10개인 행을 찾음
        let fixedBlocksInRow = document.querySelectorAll('.row' + row + '.fixed-block');
        // 행의 fixed-block의 개수가 cols와 같으면 줄 삭제
        if (fixedBlocksInRow.length === cols) {
            fixedBlocksInRow.forEach(cell => {
                cell.classList.remove("fixed-block");
                cell.style.backgroundColor = "";
                plusScore();
            });
            // 삭제된 행 위의 블럭들을 아래로 내리기
            for (let i = row - 1; i > 0; i--) {
                let selectRow = document.querySelectorAll('.row' + i);
                selectRow.forEach(div => {
                    let nowCol = parseInt(div.classList[0].replace("col", ""));
                    let nowRow = parseInt(div.classList[1].replace("row", ""));
                    let nextCell = document.querySelector('.col' + nowCol + '.row' + (nowRow + 1));
                    if (div.classList.contains("fixed-block")) {
                        nextCell.classList.add("fixed-block");
                        nextCell.style.backgroundColor = div.style.backgroundColor;
                        div.classList.remove("fixed-block");
                        div.style.backgroundColor = "";
                    }
                });
            }
        };
    });
}

deleteRow()의 코드는 다음과 같이 짰다.

1) 줄이 다 채워졌는지 확인하기

먼저 현재 블록을 cell 단위로 반복을 돌려 cell에 해당하는 row값을 class명에서 뽑아온다. 뽑아온 row값을 통해 row값이 같고 fixed-block이 포함된 블록을 querySelectorAll을 통해 fixedBlocksInRow 변수에 저장한다. 이때 fixedBlocksInRow의 길이가 cols와 같다면 한 줄이 다 채워졌다는 뜻이 되고 이를 통해 줄 삭제 여부를 확인할 수 있다.

2) 줄 삭제하기

줄 삭제는 간단하다. 줄이 다 채워져 있다면 fixedBlocksInRow를 반복 돌려 class에서 'fixed-block'을 삭제시키고, 설정된 color를 지워준 뒤 plusScore()를 호출해 점수를 올려준다.

3) 줄 내리기

줄이 삭제되었으면 삭제된 줄 위의 줄들을 아래로 내려주어야 한다. 줄을 내리는 것은 삭제된 줄의 윗줄부터 0번째 줄까지 차례대로 아래로 내려주면 된다. 다음 윗줄에 해당하는 row를 selectRow 변수에 담아주고 selectRow를 반복 돌려준다. selectRow를 반복 돌리는 cell에 'fixed-block'이 있으면 아래 cell에 'flxed-block'을 추가시키고 반복 돌려지고 있는 cell의 color를 아래 cell에 추가시켜 준다. 다음 현재 cell에 'fixed-block'을 없애고 color를 지워준다. 이렇게 하면 블록의 맨 아래줄부터 윗줄까지 반복하여 줄 삭제 여부를 확인하고 줄을 삭제시켜 준다.

3. 점수 증가

const scoreBoard = document.getElementById("score"); // 점수
const levelBoard = document.getElementById("level"); // 레벨
let score = 0; // 점수 변수
let level = 1; // 레벨 변수
let time = 2000; // interval 시간
let intervalId = null; // interval 변수 설정

점수를 증가시키기 위해 다음 코드를 추가시켜 준다.

// 점수 증가
function plusScore(){
    score++;
    scoreBoard.innerHTML = score;
    level = 1 + score/100;
    levelBoard.innerHTML = level;
    time = 2000 - level * 10;
    clearInterval(intervalId);
    intervalId = setInterval(downBlock, time);
}

점수를 증가시키는 plusScore() 함수는 다음과 같다.

score를 1 증가시키고 증가된 score를 scoreBoard에 넣어준다. level은 score를 100으로 나눈 값으로 지정하고 level을 levelBoard에 넣어준다. time값은 level에 10을 곱한 값을 2000에서 뺀 값으로 지정해 level이 증가될 때마다 내려오는 시간이 빨라지도록 했다. 다음 기존 setInterval은 초기화시키고 바뀐 time으로 setInterval을 실행시킨다.

4. 게임 시작 시 게임 초기화 시킨 뒤 시작하기

// 게임시작
function play() {
    // 초기화 작업
    score = 0;
    level = 1;
    time = 2000;
    scoreBoard.innerHTML = score;
    levelBoard.innerHTML = level;
    //  모든 블록 삭제
    let allBlock = document.querySelectorAll(".block");
    allBlock.forEach(block => {
        block.classList.remove("block");
        block.style.backgroundColor = "";
    })
    let allFixBlock = document.querySelectorAll(".fixed-block");
    allFixBlock.forEach(block => {
        block.classList.remove("fixed-block");
        block.style.backgroundColor = "";
    })
    // 시간 초기화
    clearInterval(intervalId);
    // 새로운 블록 생성
    createBlock();
    // 주기적으로 블록 내리기 시작
    intervalId = setInterval(downBlock, time);
}

play() 함수는 다음과 같이 수정했다. 게임시작을 누르면 score는 0, level은 1로 지정하여 scoreBoard, levelBoard에 출력시켜 준다. 다음 보드판에 'block'과 'fixed-block'를 제거시키고 color도 제거시킨다. 다음 기존 setInterval은 초기화시키고 바뀐 time으로 setInterval을 실행시킨다.

728x90

'javaScript' 카테고리의 다른 글

JavaScript 테트리스 만들기 - 3  (1) 2024.04.04
JavaScript 테트리스 만들기 - 2  (0) 2024.04.02
JavaScript 테트리스 만들기 - 1  (1) 2024.04.02