.gif)
- 강의를 보지 않고 스스로 만들어 봤을 때 구현은 했으나 코드가 깔끔하지 않고 스파게티 처럼 꼬여간다는 것을 느꼈다.
 - 나는 flag변수를 이용해 상태를 구분했지만 강의에서는 class에 따라 구분했는데 아주 깔끔했다 ! 그래서 class를 이용해 순서도를 다시그리고 코드를 짜 보았다.
 
대기화면은 2가지 경우인데
1. 게임시작 전 처음 시작화면과
2. 준비화면을 실수로 클릭했을 때 다시 대기화면으로 돌아간다
$screen.addEventListener("click", (e) => {
const className = $screen.className;
  if (className === "waiting") {
    showElement($progressBarContainer);
    $screen.className = "ready";
    startTimerForNow();
    handleScreenText(message.ready.title, message.ready.description);
const showElement = (element) => {
  element.style.opacity = "1";
};
const hideElement = (element) => {
  element.style.opacity = "0";
};
element를 보여줬다 사라졌다 하는게 꽤 있어서 따로 함수로 빼 주었다
const message = {
  waiting: {
    title: "시작",
    description: ` 총 기회는 5회 주어집니다.<br />다음 준비 화면에서 배경화면이 초록색이
                    되었을 때 클릭하시면 됩니다.<br />시작하시려면 현재 화면을
                    클릭해주세요.`,
  },
  ready: { title: "준비", description: "배경이 초록색이 되면 클릭해 주세요" },
  now: { title: "클릭", description: "클릭해주세요" },
};
handleScreenText(message.ready.title, message.ready.description);
object를 사용해 보고 싶어서 화면에 따라(class에 따라) 보여줘야 될 title과 descripttion을 object로 만들어서 함수에 전달해 주었다.
const startTimerForNow = () => {
  setTimeOutId = setTimeout(() => {
    $screen.className = "now";
    handleScreenText(message.now.title, message.now.description);
    startTime = new Date();
  }, Math.random() * 1000 + 2000);
};
- 클릭시 준비화면으로 바로 바꾸고 타이머를 작동해 준다
 - 2-3초 사이의 랜덤시간 후 클릭화면으로 바꿔준다
 - 클릭화면으로 바꿨을 때의 시간을 저장해준다
 
- startTime과 endTime은 이곳저곳에서 쓸 것 이기 때문에 전역으로 선언해둔다
 
else if (className === "ready") {
    //대기화면 전환 - 성급했다고 보여주기
    clearTimeout(setTimeOutId);
    $screen.className = "waiting";
    $screenTitle.textContent = "준비화면에서는 클릭이 불가합니다";
    $screenDescription.textContent = "클릭하시면 다시 준비화면으로 돌아갑니다";
  } 
준비화면을 실수로 클릭하면 대기화면으로 돌아가는데
!! 실행했던 타이머를 제거해 줘야 버그가 생기지 않는다
그렇지 않으면 대기화면일 때 타이머가 끝나 갑자기 클릭화면으로 넘어가거나
대기화면 - > 준비화면을 거쳐 타이머가 2번 실행될 수 있다
else if (className === "now") {
    attempt++;
    endTime = new Date();
    const result = endTime - startTime;
    reactionRates.push(result);
    const average = Math.floor(
      reactionRates.reduce((pre, cur) => pre + cur, 0) / reactionRates.length
    );
    showResultAndAverage(result, average);
    updateProgressBar();
    if (attempt >= opportunity) {
      finishGame(average);
      return;
    }
    handleScreenText(message.ready.title, message.ready.description);
    $screen.className = "ready";
    startTimerForNow();
  }
- progrss-bar를 다뤄주고 게임 종료시켜주기 위해 attempt를 전역으로 선언해 준다
 
= > 클릭화면에서 클릭했을 땐 성공한 것이므로 증가시켜주고 = > 화면에 보여준다- 클릭한 시간을 변수(endTime)에 할당해주고 반응속도를 계산해준다
 - 평균을 구해줘야 하기 때문에 계산값을 전역변수인 배열에 넣어주고 평균을 계산해준다 = > 화면에 보여준다
 - 준비화면으로 바꾸기 전에 5번을 진행했는지 확인해준다 ===말고 >=를 사용해 버그가 생기지 않게 범위를 넓혀준다
 - 전역에서 const 로 설정한 횟수(const opportunity=5)보다 작으면 다시 준비화면으로 돌아가고 타이머를 작동시켜준다
 
const startGame = () => {
  playing = true;
  $screen.className = "waiting";
  handleScreenText(message.waiting.title, message.waiting.description);
  hideElement($replayBtn);
  updateProgressBar();
};
const reset = () => {
  reactionRates = [];
  $result.textContent = "";
  attempt = 0;
};
const finishGame = (average) => {
  playing = false;
  $screen.className = "finished";
  const title = "결과";
  const description = `평균 ${average}ms`;
  handleScreenText(title, description);
  showElement($replayBtn);
  hideElement($progressBarContainer);
  reset();
};
- 게임이 끝나면 최종평균을 보여주는 결과화면을 보여준다
 - progress-bar를 숨기고 replay button을 활성화 시켜준다
 - 데이터들을 reset시킨다
 
const startGame = () => {
  playing = true;
  $screen.className = "waiting";
  handleScreenText(message.waiting.title, message.waiting.description);
  hideElement($replayBtn);
  updateProgressBar();
};
페이지 로딩했을 때, replay-button을 눌렸을때 게임을 실행시켜줄 함수를 따로 만든다
출처 Let's get it 자바스크립트 프로그래밍