다음 레벨 구현

YEONGHUN KO·2021년 11월 11일
0
post-thumbnail

1. 다음 레벨 구현

어떻게 하면 다음 레벨로 넘어갈 수 있을까? 내가 생각한 알고리즘은 이거다. 게임에서 이길때마다, 아이템의 갯수를 증가시킨다. 그리고 게임을 하나 더 만들어서 증가된 아이콘을 새로운 게임에 pass한다음 실행한다.

그래서 이런식으로 코드를 적었다.

let Stage = 1;

const gameStarter = (level) => {
  const IconCount = level * 2;
  const Duration = level + 4;
  const game = new GameBuilder() //
    .iconCount(IconCount)
    .gameDuration(Duration)
    .build();
  finishBannerFunc(game);
  return game;
};

gameStarter(Stage);

function finishBannerFunc(game) {
  game.onFinishBannerEvent((reason) => {
    finishBanner.hideNextStageBtn();
    switch (reason) {
      case FinishReason.win:
        finishBanner.show("win");
        sound.playWinSound();
        finishBanner.showNextStageBtn();
        break;
      case FinishReason.bug:
        finishBanner.show("lose");
        break;
      case FinishReason.timeout:
        finishBanner.show("timeout");
        sound.playLoseSound();
        break;
      case StopReason.start:
        finishBanner.hide();
        break;
      case StopReason.pause:
        finishBanner.show("restart");
        break;
      default:
        throw new Error("unvalid reason");
    }
  });

  finishBanner.setOnNextStageClick(gameStarter);

  finishBanner.setOnReplayClick(game.startFromTheVeryFirst);
}

최초 gameStarter는 stage = 1이다. 그리고 banner와 setclick 함수를 finishBannerFunc함수안에다 넣고 gameStarter 안에다가 넣었다. 이럼 어떻게 될까? 사실 replay 버튼은 문제없이 실행이 되었다. 그런데 nextclick 을 눌렀을때 아이템은 계속 증가된 채로 나왔다. 근데 문제는 타이머다. 일시정지를 누를때 타이머가 갑자기 중지가 된다. 그것도 '여러번'. 디버깅을 해보니깐. 다음 stage가 실행될때 그 전의 stage 모두 함께 실행된다는 것.

다시말해, 2단계부터(1단계는 전혀 문제없다) pause를 누를때 level1에 있는 pause, icon 까지 눌러지고, level1에 있는 timer까지 작동한다는거다. level3으로 넘어가면 level1, leve2, level3 에 있는 pause 버튼과 아이콘이 모두 함께 작동한다.

웬지 콜백지옥과 비슷한 구조라고 생각했다. 그래서 promise.then(game => '그 다음 game')으로 해결하려고 했는데 '그 다음 game'이 맨처음부터 바로 실행이 되었다. 시도는 좋았으나 promise는 게임을 순차적으로 만들어내기만 하지 내가 게임을 끝냈는지 알아차리지는 못했다.

replay버튼은 전혀 문제가 없는 걸로 보아 replay에서 뭔가 답을 찾을 수 있을것 같긴 했지만 도무지 방법이 나오지 않았다. 그래서 4일간 온갖 방법을 시도해보다가 결국 못찾고 늘어져서 dreamcoding 슬랙에 도움을 요청했다. 그러나 아무도 도와주지 않았다. 당연하다. 나또한 이 그렇게 장황한 설명과 코드를 보면 도와줄 마음이 생길것 같지 않았다. 따라서 level up에 성공한 다른 분들을 슬랙에서 찾기 시작했고 다행히 발견하여 그 분께 메세지를 보내어 코드를 공유해줄 수 있냐고 물었다. 다행히 허락하셨고 코드를 봤는데 level up 방법은 너무나 간단하였다..

새로운 문법을 적용하거나 복잡한 코드를 추가하지 않아도 되었다.

새로운게임을 만들지말고 기존 게임만 가지고 가되 다음 버튼을 클릭할때 레벨을 하나 올리고 그 레벨에 따라서 display되는 icon의 수를 늘려주기만 하면 되는거였다. 하하 그래서 추가한 코드는 아래와 같다.

2. 다음레벨 구현 코딩

finishBanner.js

this.nextStageBtn.addEventListener("click", () => {
  game.levelUp();
  this.onNextBtnClick && this.onNextBtnClick();
  this.hide();
});

일단 next버튼을 누르면 레벨이 올라가도록 했다.

gameControl.js

class Game {
  constructor(iconCount, gameDuration) {
    this.level = 1;
  }

  init(level) {
    if (level === 1) {
      this.field.displayAllIcon(this.iconCount);
    }
    if (level === 2) {
      this.field.displayAllIcon(this.iconCount + 2);
    }
    if (level === 3) {
      this.field.displayAllIcon(this.iconCount + 4);
    }
    if (level === 4) {
      this.field.displayAllIcon(this.iconCount + 6);
    }
  }

  startFromTheVeryFirst = () => {
    this.init(this.level);
  };

  levelUp() {
    ++this.level;
  }

  levelInitalized() {
    this.level = 1;
  }

  countCarrotFunc() {
    const carrotCount = this.field.carrotCount.length;
    if (carrotCount < 1) {
      if (this.level === 4) {
        this.finish(FinishReason.finalStageWin);
      } else {
        this.finish(FinishReason.win);
        this.countSpan.innerHTML = carrotCount;
      }
    } else {
      this.countSpan.innerHTML = carrotCount;
    }
  }
}

그리고 처음엔 레벨이 1이고 성공했을경우 레벨이 올라가면서 표시되는 아이템의 양도 많아지게했다. 또한 마지막 레벨에 도달했을때 완전히 끝내도록 했다.

main.js

finishBanner.setOnNextStageClick(game.startFromTheVeryFirst);

finishBanner.setOnReplayClick(game.startFromTheVeryFirst);

새로운 게임을 만들지 않고 하나의 게임을 만들고 시작버튼을 각각 부여하였다. 그래서 클릭될때마다 하나의 게임 클래스만 실행되기에 시계가 중복될 이유가 없다.

잘된다!! 드뎌 해냈다. 그럼 이제 기록 기능을 구현해보자.

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글