우찬쓰 개발블로그

자바스크립트로 웹 테트리스 만들기(2) 본문

테트리스 개발기

자바스크립트로 웹 테트리스 만들기(2)

이우찬 2021. 3. 27. 21:52
반응형

이전에 테트리스 블럭이 쌓일 공간을 만들었으니, 이제 직접 조정할 블럭과 쌓일 블럭을 만들어야겠죠?

 

저는 이 두개를 stackedBlockcontrolBlock으로 이름붙였습니다.

 

그리고 각 블럭을 초기화 해봅니다.

const widthBlockCount = 10;
const heightBlockCount = 25;

let stackedBlock = new Array(widthBlockCount);
let controlBlock = new Array(widthBlockCount);

initBlockArray(stackedBlock);
initBlockArray(controlBlock);

function initBlockArray(blockArray) {
  for (let x = 0; x < widthBlockCount; x++) {
    blockArray[x] = new Array(heightBlockCount);
  }

  for (let x = 0; x < widthBlockCount; x++) {
    for (let y = 0; y < heightBlockCount; y++) {
      blockArray[x][y] = false;
    }
  }
}

 

해당 공간에 블럭이 쌓여있으면 true, 없으면 false로 간단히 정하였습니다.

 

나중엔 색상데이터도 저장해야하고, 기타 속성이 추가 되겠지만, 저의 성격상 하나씩 살을 붙이는걸 좋아하기 때문에 시작은 이렇게 해봅시다.

 

이제 블럭을 그리는 함수도 추가해야겠죠?

 

function drawBlocks() {
  for (let x = 0; x < widthBlockCount; x++) {
    for (let y = 0; y < heightBlockCount; y++) {
      if (stackedBlock[x][y]) {
        ctx.fillStyle = "black";
      } else {
        ctx.fillStyle = "gray";
      }

      if (controlBlock[x][y]) {
        ctx.fillStyle = "blue";
      }

      ctx.fillRect(
        borderWidth * x + blockSize * x,
        borderWidth * y + blockSize * y,
        blockSize,
        blockSize
      );
    }
  }
}

 

stackedBlock에 쌓인 블럭에서 쌓여있으면 검은색, 안쌓여있으면 회색으로 그려지도록 하고, 내가 컨트롤할 블럭은 파란색으로 했습니다.

 

이제 시간이 흐를때마다 블럭이 한칸씩 떨어지도록 해볼게요.

 

let testButtonOn = false;
let timeId = null;

function onClickTestButton() {
  if (testButtonOn) {
    clearInterval(timeId);
  } else {
    timeId = setInterval(flowGravity, 300);
  }
  testButtonOn = !testButtonOn;
}

function flowGravity() {
  let collisionCheckTmpArray = copyBlockArray(controlBlock);
  if (isCollided(collisionCheckTmpArray, stackedBlock)) {
    addBlocksToStackedArray(controlBlock, stackedBlock);
    addNewControlBlock(controlBlock);
  } else {
    controlBlock = collisionCheckTmpArray;
  }
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBlocks();
}

 

디버깅을 위해 테스트 버튼을 하나 만들어서 내려오는 블럭을 언제든 멈출 수 있게 했습니다.

 

그리고 충돌하고나면 controlBlock을카피해서 stacktedBlock에 옮겨줘야겠죠?

 

충돌 함수와 카피 함수를 간단히 만들고, 이제 실행 결과를 볼까요?

매번 [5][0]에 블럭이 생성되게 했더니, 매우 잘 쌓이는 것을 볼 수 있습니다.

 

이정도 했더니 벌써 거의 다 만든거 같은 기분이 드네요.

 

근데 실제 테트리스 블럭 모양이 내려오면 좀 더 그럴듯 할거같죠?

 

그래서 테트리스 블럭 설계도를 추가해봅니다.

 


/**
 ****□□□□****
 **/
function addTypeOneBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[5][0] = true;
  controlBlocks[6][0] = true;
  controlBlocks[7][0] = true;
}

/**
 ****□□□*****
 *****□******
 **/
function addTypeTwoBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[5][0] = true;
  controlBlocks[5][1] = true;
  controlBlocks[6][0] = true;
}

/**
 *****□□*****
 *****□□*****
 **/
function addTypeThreeBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[4][1] = true;
  controlBlocks[5][0] = true;
  controlBlocks[5][1] = true;
}

/**
 ****□□******
 *****□□*****
 **/
function addTypeFourBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[5][0] = true;
  controlBlocks[5][1] = true;
  controlBlocks[6][1] = true;
}

/**
 *****□□*****
 ****□□******
 **/
function addTypeFourBlock(controlBlocks) {
  controlBlocks[4][1] = true;
  controlBlocks[5][0] = true;
  controlBlocks[5][1] = true;
  controlBlocks[6][0] = true;
}

/**
 ****□□□****
 ******□****
 **/
function addTypeFiveBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[5][0] = true;
  controlBlocks[6][0] = true;
  controlBlocks[6][1] = true;
}

/**
 ****□□□****
 ****□*******
 **/
function addTypeSixBlock(controlBlocks) {
  controlBlocks[4][0] = true;
  controlBlocks[4][1] = true;
  controlBlocks[5][0] = true;
  controlBlocks[6][0] = true;
}

 

그리고 랜덤되게 블럭이 생성되어 내려오도록 해볼게요

function addNewControlBlock(controlBlocks) {
  clearBlockArray(controlBlocks);
  let type = Math.floor(Math.random() * 7 + 1);

  switch (type) {
    case 1:
      addTypeOneBlock();
      break;
    case 2:
      addTypeTwoBlock();
      break;
    case 3:
      addTypeThreeBlock();
      break;
    case 4:
      addTypeFourBlock();
      break;
    case 5:
      addTypeFiveBlock();
      break;
    case 6:
      addTypeSixBlock();
      break;
    case 7:
      addTypeSevenBlock();
      break;
  }
}

와우! 뭔가 그럴듯해 졌습니다.

 

마치 테트리스 게임에서 아무것도 안하고 가만히 있으면 나올것 같은 것 같은 장면이네요.

 

여기까지만 만들어도 참 마음이 뿌듯하네요.

 

하지만 여기서 멈출 수 없겠죠?

 

코드도 천천히 정리해가면서 다음 진행을 해봅시다.

 

3부에 계속..

반응형
Comments