미새문지

크래프톤 정글 week16, day118 - 대기 방 악기 선택 구현, 구현 중 에러 터진거 해결 본문

크래프톤 정글/TIL

크래프톤 정글 week16, day118 - 대기 방 악기 선택 구현, 구현 중 에러 터진거 해결

문미새 2024. 5. 4. 23:32
728x90

대기 방에 악기 선택 추가

대기 방에 악기 선택을 넣기 위해 서버에서 기존에 보내주던 roomData 인자에 nickname과 instrument를 객체로 전달해줬다. 근데 프론트에서 기존에 받던 roomData.nickname이 아닌 roomData.playerStatus.nickname이런식으로 한번더 안으로 접근했어야 했는데 이 부분을 놓쳐서 에러 수정에 시간이 좀 걸렸다. 지금 생각해보면 바로 값이 제대로 들어오는지부터 확인했어야 했는데, 코드 정리를 못해 많이 더러워서 더 헷갈렸던 것 같다.

 

이 후 값을 받아 webCam 컴포넌트까지는 가져왔는데 기존에 플레이어를 받아와 준비상황까지 합치는 코드가 있었는데,

  const [playerStatuses, setPlayerStatuses] = useState(
    players.reduce((acc, player) => ({...acc, [player]: false}), {})
  );

이 부분을 제대로 이해하지 못하고 급하게 사용하고 있었다.

그런데 여기에 기존에 받아오던 players를 instrument와 함께 객체로 담아오기 때문에, 이 부분을 수정했어야 했는데 코드를 이해를 못했어서 지피티에 막 물어보면서 하느라 시간이 오래 걸렸었다. 이 후 값 받아오는 타입이랑 흐름을 파악하고 코드를 처음부터 객체로 받아서 준비상황을 추가시켰다.

  const [playerStatuses, setPlayerStatuses] = useState({});
  
  // 인자 값 넣기
  useEffect(() => {
    setPlayerStatuses(
      players.reduce((acc, player) => {
        acc[player.nickname] = {
          nickname: player.nickname,
          instrument: player.instrument,
          isReady: false
        };
        return acc;
      }, {})
    );
  }, [players]);
  
    // 레디 버튼
  const readyBtnClick = (nickname) => {
    if(myNickname === nickname) {
      socket.emit("ready", (res) => {
        console.log("ready res", res);
      })
  
      setPlayerStatuses(prevStatuses => ({
        ...prevStatuses,
        [nickname]: {
          ...prevStatuses[nickname],
          isReady: !prevStatuses[nickname].isReady
        }
      }));
    } else {
      return;
    }
  }

이런식으로 기존 playersStatuses에 객체로 만들어두고 안에 인자로 받아온 값과 준비 상황은 기본적으로 false로 되어 있어 false도 함께 넣어줬다.

이 후 값을 제대로 받아오게 되어 화면에 뿌려주려고 했다가 기존 코드는 배열 값을 뿌려줬는데 현재는 playersStatuses값이 객체기 때문에 object로 객체를 변환해서 뿌려줘야 했다. 이 부분에서도 시간을 좀 썼다.

return (
    <>
      {/* 플레이어 들어오면 div가 늘어나는 방식 */}
      <WebCamBox>
      {Object.entries(playerStatuses).map(([nickname, {instrument, isReady}], index) => (
          <PlayerContainer key={index}>
            <WebCamInfo>
              <WebCamTop>
                <Mediapipe soundTimes={this.state.soundTimes} />
                <HitMiss>
                  <p>0</p>
                  <p>0</p>
                </HitMiss>
              </WebCamTop>
              <div>
                <h2>{nickname}</h2>
                <h2 onClick={() => findingInstrument(nickname)}>{instrument}</h2>
              </div>
            </WebCamInfo>
            {nickname === hostName ? (
              <ReadyBtn onClick={() => startGameHandler()}>시작</ReadyBtn>
            ) : (
              <ReadyBtn
                isReady={isReady}
                onClick={() => readyBtnClick(nickname)}
              >
                {isReady ? "준비 완료" : "대기 중"}
              </ReadyBtn>
            )}
          </PlayerContainer>
        ))}
          {instruModal && (
            <InstrumentModal>
              {instrumentList.map((instrument) => (
                <ul key={instrument.id}>
                  <li onClick={() => selectedInstrument(instrument.instrumentName)}>
                    {instrument.instrumentName}
                  </li>
                </ul>
              ))}
            </InstrumentModal>
          )}
      </WebCamBox>
    </>
  )

이 부분은 어느정도 완료하고 시간이 생길 때 나중에 다시 복습하면서 코드를 완벽히 이해할 생각이다. 

 

에러 해결 후, 제대로 받아온 걸 확인하고 악기도 화면에 뿌려줬다. 노래를 선택할 때 방식으로 클릭 시 모달창이 켜지고 거기서 선택한 값에 따라 소켓을 이용해 악기가 실시간으로 변경되고 보이는지, 다른 사람의 악기는 선택을 못하게 하는 로직을 구현했다.

 

학습 시간 : 10 ~ 25시

 

728x90