테트리스 게임 개발 중, 고스트 블록이 순차적으로 렌더링되는 버그를 발견했다.
현재 블록과 고스트 블록의 위치가 동시에 렌더링되지 않아서 생기는 버그같았다.
고스트 블록을 구현했는데, 현재 조각이 착지할 위치를 가시화해줬다! ( 바로 떨어뜨리려면 필요한 기능)
근데, 고스트 블록이 이게 한줄씩 렌더링되면서 처음에 좀 사용자로 하여금 불쾌할만하게 차근차근 블록이 그려지는 버그가 발생했다.
fillGhost
함수를 수정하여 고스트 블록을 더 효율적으로 렌더링하도록 했습니다.수정된
fillGhost
함수fillGhost(ghostY: number, color: string) { for (let r = 0; r < this.activeTetromino.length; r++) { for (let c = 0; c < this.activeTetromino[r].length; c++) { if (this.activeTetromino[r][c]) { if (this.y + r >= 0 && this.x + c >= 0) { if (color === this.game.VACANT) { this.game.drawSquare(this.game.ctx, this.x + c, ghostY + r, this.game.board[ghostY + r][this.x + c], false); } else { this.game.drawSquare(this.game.ctx, this.x + c, ghostY + r, color, true); } } } } } }
1.ghostPositions
배열에 고스트 블록이 차지할 모든 좌표를 저장하고,
2.고스트 블록을 그리기 전,clearRect
를 사용해 보드 전체를 지우고drawBoard
로 canvas에 다시 그려준다
3.ghostPositions
에 저장된 좌표를 기반으로 고스트 블록을 한 번에 그린다
4.마지막으로 현재 블록을 다시 draw해서 표시!
결과
fillGhost(ghostY: number, color: string) { const ghostPositions: { x: number; y: number }[] = []; for (let r = 0; r < this.activeTetromino.length; r++) { for (let c = 0; c < this.activeTetromino[r].length; c++) { if (this.activeTetromino[r][c]) { if (ghostY + r >= 0 && this.x + c >= 0) { ghostPositions.push({ x: this.x + c, y: ghostY + r }); } } } } this.game.ctx.clearRect(0, 0, this.game.COL * this.game.SQ, this.game.ROW * this.game.SQ); // 현재 블록과 고스트 블록이 그려진 영역 전체 지우기 this.game.drawBoard(); ghostPositions.forEach(pos => { if (color === this.game.VACANT) { this.game.drawSquare(this.game.ctx, pos.x, pos.y, this.game.board[pos.y][pos.x], false); } else { this.game.drawSquare(this.game.ctx, pos.x, pos.y, color, true); } }); this.draw(); // 현재 블록 다시 그리기 }