테트리스 게임 고스트 블록 렌더링 버그 해결

·2024년 6월 30일
0

swjungle일지

목록 보기
10/11
post-thumbnail

테트리스 게임 개발 중, 고스트 블록이 순차적으로 렌더링되는 버그를 발견했다.
현재 블록과 고스트 블록의 위치가 동시에 렌더링되지 않아서 생기는 버그같았다.

버그 발생!

고스트 블록을 구현했는데, 현재 조각이 착지할 위치를 가시화해줬다! ( 바로 떨어뜨리려면 필요한 기능)
근데, 고스트 블록이 이게 한줄씩 렌더링되면서 처음에 좀 사용자로 하여금 불쾌할만하게 차근차근 블록이 그려지는 버그가 발생했다.

고스트 블록 문제 스크린샷 1 고스트 블록 문제 스크린샷 2

코드 수정

  • 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(); // 현재 블록 다시 그리기
}

개선 완료!

고스트 블록 문제 해결 후 스크린샷

드디어 고스트 블록이 한번에 등장과 함께 그려진다!


profile
기억보단 기록을

0개의 댓글