1. 배경
1부에서 충돌 감지를 구현했다. 2부는 꽉 찬 줄을 삭제하고 점수를 계산하는 로직이다.
2. 줄 삭제 구현
function clearLines() {
const remainingLines = board.value.filter(row =>
!row.every(cell => cell !== 0)
)
const deletingLines = BOARD_ROWS - remainingLines.length
const emptyLines = Array.from(
{ length: deletingLines },
() => Array(BOARD_COLS).fill(0)
)
board.value = [...emptyLines, ...remainingLines]
return deletingLines
}
3. 배운 개념 — 참조 vs 값
처음에 Array(3).fill([0,0,0])으로 빈 줄을 만들었는데 버그가 생겼다. 배열은 값이 아니라 주소를 저장해서 fill로 복사하면 같은 배열을 가리키게 된다. 하나를 바꾸면 전부 바뀌는 문제가 생긴다.
Array.from + 콜백을 쓰면 매번 새 배열을 만들어서 독립적이다.
// 위험 — 같은 배열 공유
Array(3).fill([0,0,0])
// 안전 — 독립된 배열 생성
Array.from({ length: 3 }, () => [0,0,0])
4. 점수 시스템 구현
function addScore(clearedLines) {
const earned = LINE_SCORES[clearedLines] * level.value
score.value += earned
lines.value += clearedLines
level.value = Math.floor(lines.value / 10) + 1
if (score.value > bestScore.value) {
bestScore.value = score.value
localStorage.setItem('tetris_best_score', score.value)
}
return earned
}
5. 배운 개념 — localStorage
localStorage는 브라우저에 데이터를 영구 저장하는 공간이다. 게임을 껐다 켜도 최고 점수가 남아있는 이유가 이것이다.
주의할 점은 localStorage에만 저장하면 Vue가 변경을 감지하지 못해서 화면이 안 바뀐다. bestScore.value도 같이 갱신해줘야 한다.
6. 마무리
filter + every 조합은 비슷한 케이스가 오면 이해할 수 있는 정도가 됐다. 참조 공유 문제는 코드 분석하면서 이해가 됐다.
'프로젝트 > 레트로 테트리스' 카테고리의 다른 글
| Redis 제거와 복구코드 재발급 기능 구현 기록 (TDD + NestJS 트러블슈팅) (4) | 2026.06.15 |
|---|---|
| 테트리스 레트로 개발 회고 — 성능 개선부터 배포까지 (0) | 2026.06.10 |
| Claude Code로 테트리스 만들기 4부 - 모바일 터치 조작 구현 (0) | 2026.04.21 |
| Claude Code로 테트리스 만들기 3부 - 반응형 레이아웃 구현 (0) | 2026.04.20 |
| Claude Code로 테트리스 만들기 1부 - 충돌 감지 구현 (0) | 2026.04.19 |