리액트

[React] Date 함수를 사용해 현재 초를 소수 단위로 정교하게 값을 비교하기 (getSeconds() , getMilliseconds())

joheamin 2025. 1. 24. 02:28

현재 내가 만들고있는 미니게임이 있다.

 

 

 

🔴 게임 설명

게임 시작 버튼을 누르면 3초 카운트 다운을 한 뒤 

10초 동안 랜덤으로 공격이 들어오고 타이밍에 맞춰 방어를 하면 성공 못하면 실패이다.

 

결과 판정을 위한 시간 계산을 요약해서 설명하자면

 

🕛 시작 버튼 클릭 시간 + 공격 타이밍 시간(1~10초) + 카운트다운 시간(3초)  =  통과 시간

만약 현재시각 10초쯤에 클릭을 하였고 공격 타이밍은 랜덤으로 3초가 나왔다고 가정한다면

카운트 다운 3초  까지 합산하면 통과시간은 16초 가 된다.

 

그리고 난 뒤 방어 버튼 클릭한 시간을 구하여 비교를 하여 결과를 구하는 방식이다.

 

❓현재 시간의 초 단위를 구하는 방법

const date = new Date();
date.getseconds();

 

 

🤔 하지만 반응속도 게임 이라면 초 단위가 아니라 좀 더 정밀한 수치로 계산해야한다.

 

그래서 생각한 방법들이 있는데 차례로 나열해보겠다.

 

 

 

 

 

 

 

1️⃣ 첫번째 방안

parseFloat(pass) - 0.5 < clickSec && parseFloat(pass) + 0.5 > clickSec ? 성공 : 실패

 

통과시간을 소수점으로 연산해 만약 10초가 통과 시간이라면 

9.5 ~ 10.5 사이에 들어오면 성공이다.

 

그런데 이렇게 했을때 문제점이 getSeconds()는 초 단위까지만 구한다.(정수)

그렇다면 소수점으로 바꾼다한들 반드시 제한 될것이다.

 

반응속도 게임인 만큼 웬만하면 통과시간 과 방어 시간을 비교했을때 초 단위는 똑같을것이다.

 

그러면 결국 대부분의 결과는 이렇게 될것이다.

통과시간 - 0.5 < 방어 시간 < 통과시간 + 0.5    

 

너무 성공의 범위가 쉽고 안정적인 셈이다.

 

 

 

 

2️⃣ 두번째 방안

초 단위로는 안되니 더욱 정밀한 단위를 구해야한다.

이때 발견한 것이 Date객체의 getMilliseconds() 이다. 

 

밀리세컨드를 구하는 메서드이다.

 

밀리세컨드란 1/1000초를 뜻하는 시간 단위  이며, 

메서드는 0~999 범위의 정수를 반환하게 된다.

 

0.5초면 밀리세컨드 단위로 500 이된다는것이다.

 

 

 

 

그런데 여기서 문제점은 getMillseconds()는 0~999 까지로만 반환하기때문에 

만약  20초일 경우 2000 이 아니라 0을 반환한다. 

 

이렇게 되면 정확한 계산이 안된다.

 

💡그래서 생각해낸 방법

밀리세컨드가 1초 * 1000 이고 getMillSecond() 가 소수점 범위 밖에 반환을 못한다면 ?

 

🕛 현재 초 * 1000 + 현재 초.소수점 

이렇게 구한다면 정확한 시간의 소수 단위 까지 알아낼 수 있다.

 

코드로 구현하자면 이러하다.

1000 * date.getSeconds() + date.getMilliseconds();

 

그렇다면 공격 타이밍 숫자도 곱하기 1000을 하고 

카운트 다운 숫자도 곱하기 1000을 하여 통과 시간을 계산 해보자.

 

const date = new Date();

//시작 시간
cosnt startTime = 1000 * date.getSeconds() + date.getMilliseconds(); 

//방어 시간
const clickSec = 1000 * date.getSeconds() + date.getMilliseconds();

//통과 시간
const pass = startTime + attackTiming * 1000 + 3000;

//결과 판정
pass - 300 < clickSec && pass + 400 > clickSec ? 성공 : 실패;

 

만약 내가 30.6초에 시작을 클릭했고 공격 타이밍이 3초로 걸렸을때를 가정하면

 

시작시간 30000(30초)

시작시간 밀리세컨트 600(0.6초)

 

공격 타이밍 3000(3초)

 

카운트 다운 3000(30초)

 

 다 더해서  통과시간 : 36600(36.6초) 

 

위 코드대로 결과 판정을 한다면 

 

내가 방어 버튼을 36.3초 ~ 34초 안에만 클릭하면 성공인 셈이다.

 

끝