24/1/9 반응속도 게임(response check)

2024. 1. 10. 08:52카테고리 없음

이건 내가 만든 게임은 아니다 ㅋㅋㅋㅋ 팀원 코드인데 훑어봅시다. 허락안맡고 올리는중 ㅋㅋㅋ til쓸게 없어용 ㅜ

<Response.jsx> 

import React, { useState, useRef, useCallback } from "react";
import {
  StContainer,         //우리 팀원분 깔끔한 성격이라 스타일드 컴포넌트 다 파일 분리하셨음 
  Stscreen,
  StText,
  StTime,
  StContent,
  StBtn,
} from "./style";

const ResponseCheck = () => {
  const [state, setState] = useState("waiting");
  const [message, setMessage] = useState("클릭해서 시작하세요 !");  //흐음 유즈스테이트 3개
  const [result, setResult] = useState([]);
  const timeout = useRef(null);         //유즈레프도 세게 호오~
  const startTime = useRef(0);
  const endTime = useRef(0);        //시간관한 걸 참조하는듯

  const onClickScreen = useCallback(() => {   //오 useCallback이다 메모이제이션이라 흐음
    if (state === "waiting") {                              //스테이트가 웨이팅일떄
      timeout.current = setTimeout(() => {   //타임아웃에 커런트속성에 셋타임아웃을 다셨군
        setState("now");                                 //waiting에서 now로 바뀌고
        setMessage("지금 클릭 !!");         //메시지를 바꿔주고
        startTime.current = new Date();       //스타트 타임이라는 curreng 속성에 현재시간 할당
      }, Math.floor(Math.random() * 1000) + 2000); // 2초~3초 랜덤  //랜덤으로 0~1숫자 선택되고 
      setState("ready");                                   //정수로 2초 3초가 선택되고 // 상태를 ready로 바꿔주고
      setMessage("초록색이 되면 화면을 클릭하세요 !");     //메시지 바꿔주고
    } else if (state === "ready") {           //스테이트가 ready일때
      // 성급하게 클릭
      clearTimeout(timeout.current);       //위에 setTimeout을 바로 종료시키고
      setState("waiting");                        //상태를 waiting으로 놔둔다.
      setMessage(                                //메시지를 바꿔주고
        <>
          너무 성급해요 ! <br />
          초록색이 되면 클릭하세요 !
        </>
      );
    } else if (state === "now") {         //상태가 now일때
      // 반응속도 체크
      endTime.current = new Date();    //endTime current속성에 현재시간 주고
      setState("waiting");                       //상태를 waiting으로 바꾸고
      setMessage("화면을 클릭하면 시작합니다.");        //메시지 바꿔주고
      setResult((prevResult) => {         //결과 스테이트를 설정하는구먼
        return [...prevResult, endTime.current - startTime.current];   //예전의 결과값들을 가져오고
      });                                                                       //아까 new.date()로 만든 시간값들을 빼줘서 
    }                                                               //반응속도 시간값도 요소로 배열에 넣어주고
  }, [state]);   //state값 변화일떄만 usecallback 내부 함수 상태변화

  // 평균 반응 속도 --> 초기화 버튼
  const onReset = useCallback(() => {
    setResult([]);                  //리셋하는 스테이트 //배열을 비우는로직
  }, []);                             //여기는 마운트 됐을때 설정된 함수를 계속쓰는군

  // 평균 반응 속도
  const renderAverage = () => {
    return result.length === 0 ? null : (   //배열에 길이가 0이면 보여주는거 없고
      <StContent>
        <StTime>                                             //결과값들의 reduce매서드로 다더한값의 길이로 나눠서
          {`평균 반응 속도 :  ${                                  //평균값을 구하시는군
            result.reduce((a, c) => a + c) / result.length
          } ms`}
        </StTime>
        <StBtn onClick={onReset}>Reset</StBtn>     //이건 리셋버튼이라서 누르면 배열 비울테고
      </StContent>
    );
  };

  return (
    <>
      <StContainer>
        {renderAverage()}    //오 이건 신박하다. 함수의 리턴이 태그형식이니까 그걸 보여주는구나
        <Stscreen className={state} onClick={onClickScreen}>   //위에 첫 유즈콜백이 일어나는구먼
          <StText>{message}</StText>    //메시지 보여주는거고       
        </Stscreen>                                //className에 state가 달려있구만 이걸로 css변화시키시는군
      </StContainer>
    </>
  );
};

export default ResponseCheck;

 

<style.js> 모아놨던 스타일드 컴포넌트

import styled from "styled-components";

export const StContainer = styled.div`
  margin-top: 100px;
  display: flex;
  justify-content: center;
  flex-direction: column
  align-items: center;
  text-align: center;
`;

export const Stscreen = styled.div`
  margin-top: 20px;
  width: 600px;
  height: 500px;
  display: flex;
  justify-content: center;
  text-align: center;
  border-radius: 20px;
  user-select: none;
 
  &.waiting {                               //와 여기가 신박하네  Stscreen 태그인거는 다 똑같은데
    background-color: lightgray;     //className속성자체에 state를 할당해서 보이는 css가 달라지시는구먼
    font-size: 30px;
  }                                      //기다려상태일때는 밝은 회색

  &.ready {
    background-color: gray;       //레디일때는 회색
    color: white;
    font-size: 30px;
  }

  &.now {
    background-color: var(--green);  //나우 일때는 초록색
    color: white;
    font-size: 30px;
  }
`;

export const StText = styled.div`
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
`;

export const StTime = styled.div`
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  font-size: 20px;
`;

export const StBtn = styled.button`
  cursor: pointer;
  width: 100px;
  height: 30px;
  background-color: var(--yellow);
  margin-top: 20px;
  margin-bottom: 20px;
  border-radius: 5px;
  font-size: 20px;
  color: white;
  border: none;
  padding: 5px;
  align-items: center;
  display: flex;
  justify-content: center;

  &:hover {
    transform: scale(1.05);       //호버일때 크기변화
  }
`;

export const StContent = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  width: 600px;
  height: 50px;
`;

 

//흐음 콜백함수 쓴 이유는 state함수가 세개라 리랜더링이 잦아서 그런신거 같고
//스테이트가 waiting 일때 누르면  일단 그시간을 기록하고 또한 실행되는데 2~3초가 걸리는 settimeout 이 시작된다. 그전에 아래로직에서 일단스테이트가 ready

//상태가 되고 만약 2~3초 안기다리고 클릭을 한번더하면 다시 waiting스테이트가 되면서 clearTimeOut으로 settimeout

//시작전에 끝내고 

//만약 성급하게 누르지 않고 기다렸다가 .  settimeout이 제대로발동되서  스테이트가 now일때 누르면 그때 시간을기록

//하는구먼 그리고 다시 스테이트들을 초기상태로 해주고 기록을 배열에 넣고

 

//이상으로 심화플러스주차 팀과제때 우리 팀장님 코드를 살펴보았다. 

//좋은 코드였다. 야미~