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

[JavaScript] 테트리스 웹 게임 만들기 (4) 블록 이동 및 전환

by _temp 2022. 2. 15.

테트리스 웹 게임 만들기 (4) - 블록 이동 및 전환

 

1. 이벤트 정의

테트리스 js의 생성자에 다음 이벤트를 추가했다.

위에서 3개는 좌,우,하 로 블록 이동이고,

이어서 방향전환(위), 블록드랍(스페이스바)이다.

//events
    document.addEventListener('keydown', (e) => {
      switch (e.keyCode) {
        case 39:
          this.moveBlock('m', 1)
          break
        case 37:
          this.moveBlock('m', -1)
          break
        case 40:
          this.moveBlock('n', 1)
          break
        case 38:
          this.changeDirection()
          break
        case 32:
          this.dropBlock()
          break
        default:
          break
      }
    })

 

1. 블록 이동

 

moveBlock함수 : where방향으로 amount만큼 현재 블럭의 값을 수정해준다.

  moveBlock(where, amount) {
    this.movingBlock[where] += amount
    this.checkNextBlock(where)
  }

 

렌더 블록을 다음과 같이 수정해 주었다.

이전의 위치의 모든 요소들의 클래스를 삭제해주는 로직을 추가했다.

  renderBlock() {
    const { type, direction, n, m } = this.movingBlock
    // 추가
    const temp = document.querySelectorAll('.moving')
    temp.forEach((x) => {
      x.classList.remove(type, 'moving')
    })
    // 여기까지
    Blocks[type][direction].forEach((block) => {
      const x = block[0] + n
      const y = block[1] + m
      const target = this.stage.childNodes[x].childNodes[y]
      target.classList.add(type, 'moving')
    })
  }

 


 

2. 블록 전환

 

방향을 바꿔주는 함수를 추가해주고 3이면 0으로 나머지는 +1씩 해준다.

  changeDirection() {
    const direction = this.movingBlock.direction
    direction === 3
      ? (this.movingBlock.direction = 0)
      : (this.movingBlock.direction += 1)
    this.renderBlock()
  }

 


 

3. 블록 드랍

 

현재 downInterval를 clear하고 8ms마다 아래로 이동하게 만든다.

그럼 순식간에 drop하는 효과가 나타난다.

  dropBlock() {
    clearInterval(this.downInterval)
    this.downInterval = setInterval(() => {
      this.moveBlock('n', 1)
    }, 8)
  }

 

 

 

여기까지 블록의 이동과 방향전환에 대해서 코딩을 했다. 아주 큰 문제점이 있다.

바로 좌우이동시, 블록이 테이블 바깥으로 넘어가는 것drop시, 블록이 맨 아래 도달했음에도 테이블 바깥으로 나가버린다.

하나 더, 방향전환시, 블록이 테이블 바깥으로 나가는 현상도 있다.

다음에 이에 대한 코딩을 할 것이다.

 

아이디어는 바로 renderBlock을 하기 전에 checkBlock를 하고 renderBlock을 호출하는 방향으로 정했다.