ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 지뢰찾기를 만들어보자 #7 - 게임 스코어 구현
    기술 관련/etc 2022. 10. 5. 20:21

    지난번 지뢰찾기의 난이도 조절을 대해 다루어 보았었다. 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 지뢰찾기에서와 같이 노란 스마일 얼굴 버튼으로 게임 시작/종료를 구성 하는 내용을 다루어 보도록하겠다.

    댓글

Designed by Tistory.