지뢰찾기를 만들어보자 #7 - 게임 스코어 구현
지난번 지뢰찾기의 난이도 조절을 대해 다루어 보았었다. https://mc500.tistory.com/673 이번 글에서는 좀 더 게임답게 게임 점수에 대한 부분을 만들어 보도록 하자.
지뢰찾기의 승리조건은 지뢰가 없는 안전한 곳을 다 찾는 것이다. 그리고 한 번이라도 지뢰를 건드리면 실패다. 따라서, 게임 점수로서 정할만한 것이 게임을 시작해서 승리까지 걸린 시간이 가장 적절한 것으로 보이므로, 가장 빠른 시간에 승리를 한 것을 최고 점수로 기록할 수 있도록 한다.
게임 기록은 어딘가에 저장을 해 놓을 수 있는 방법이 있지만 나중에 개선 사항으로 남겨 두기로하고, 이번 글에서는 단지 기능만 구현하기로 한다.
우선 게임 점수와 시작 시간에 대한 변수를 먼저 구성한다.
highscores: {
beginner: 999,
intermediate: 999,
expert: 999,
},
start_time: 0,
elapsed_time: 0,
물론 elapsed_time은 initGame() method 에서 0으로 초기화 해주어야 한다. 그리고 나서 점수를 표시할 HTML을 추가한다.
<div>
<span>{{elapsed_time}} sec(s)</span>
</div>
<br>
대략 다음과 같은 모습이 된다.
게임을 시작하면 타이머를 실행해서 그 때 부터 일정 시간이 지났을 때 정보를 갱신해 주도록 해야하고, 게임이 끝났을 때는 타이머를 중지하고 현재 시간을 기준으로 최종 점수를 입력하게 한다.
우선은 게임 종료 시점에 gameover=true로 처리하는 것을 finishGame()이라는 method를 만들고 호출하도록 코드를 변경한다. 그리고, 이 때 성공 실패 정보도 같이 받도록 한다.
finishGame(win) {
this.gameover = true
if (win) {
this.alert('You Win!')
} else {
this.alert('Bomb!')
}
},
게임을 시작하는 시간은 New Game 버튼을 클릭했을 때가 아닌 상자를 제일 먼저 클릭 했을 때가 되어야 한다. 이를 위해 첫 번째 클릭 여부를 판단하는 변수가 있어야 한다. 그런데 새로이 추가 하기보다는 게임 시작 시간인 start_time 변수 값이 0인 경우 아직 게임이 시작되지 않은 것으로 여길 수 있으므로 이를 이용하도록 한다.
this.canvas.addEventListener("mousedown", function(evt) {
let x = Number.parseInt(evt.offsetX/self.box_width)
let y = Number.parseInt(evt.offsetY/self.box_width)
evt.preventDefault()
evt.stopPropagation()
if (self.gameover) {
return false
}
if (self.start_time == 0) {
self.start_time = new Date().getTime()
self.scoreIntervalId = setInterval(() => {
let diff = (new Date().getTime()) - self.start_time
self.elapsed_time = Math.round(diff/1000)
}, 1000)
}
이제 finishGame() 에서 타이머를 중지하고 최종 점수를 저장한다.
finishGame(win) {
let record = this.elapsed_time
if (this.scoreIntervalId) {
clearInterval(this.scoreIntervalId)
this.scoreIntervalId = undefined
}
this.gameover = true
if (win) {
this.alert('You Win!')
this.highscores[this.level] = record
} else {
this.alert('Bomb!')
}
},
또한, 게임을 포기하고 새로 게임을 시작하는 경우가 있으므로 initGames()에도 타이머를 중지 코드를 작성한다.
initGames() {
this.gameover = false
this.cleared = 0
this.start_time = 0
this.elapsed_time = 0
this.flags = 0
if (this.scoreIntervalId) {
clearInterval(this.scoreIntervalId)
this.scoreIntervalId = undefined
}
추가로 현재 지뢰의 갯수와 깃발의 수를 비교하여 남은 지뢰의 수를 알 수 있도록 HTML에 정보를 추가해준다.
<div>
<span>{{elapsed_time}} sec(s), {{mines - flags}} left</span>
</div>
다음 글에서는 Windows 지뢰찾기에서와 같이 노란 스마일 얼굴 버튼으로 게임 시작/종료를 구성 하는 내용을 다루어 보도록하겠다.