Cocos Creator

실시간 시간 표시 (Timer)

밀하우스 마나스톰 2022. 3. 18. 12:42

 

1. 로컬 타임

update(dt:number){
    let today = new Date();
    let year = today.getFullYear();
    let month = ('0' + (today.getMonth() + 1)).slice(-2);
    let day = ('0' + today.getDate()).slice(-2);
    let hours = ('0' + today.getHours()).slice(-2); 
    let minutes = ('0' + today.getMinutes()).slice(-2);
    let seconds = ('0' + today.getSeconds()).slice(-2);
    this.label.string = day + '/' + month + '/' + year + '\n' + hours + ':' + minutes + ':' + seconds;
}

위의 update를 통해 초기화된 label.string을 UI 오브젝트로 출력하면 된다.

 

today는 위와 같이 년, 월, 일, 시간, 분, 초, 시간 타입으로 구성돼있음을 확인할 수 있다.

 

그리고 getMonth, GetDate와 slice 함수를 이용해 각 단위별로 잘라서 원하는 형태로 출력할 수 있다.

 

new Date()는 로컬 타임. 즉 디바이스의 시간을 가져온다.

 

디바이스의 시간을 인위적으로 변경하면 이 값도 변경된다.

 

 

update(dt:number){
    let today = new Date();
    let rawSeconds = today.getSeconds();
    if (rawSeconds == this.lastSeconds) return;
    
    let year = today.getFullYear();
    let month = ('0' + (today.getMonth() + 1)).slice(-2);
    let day = ('0' + today.getDate()).slice(-2);
    let hours = ('0' + today.getHours()).slice(-2); 
    let minutes = ('0' + today.getMinutes()).slice(-2);
    let seconds = ('0' + rawSeconds).slice(-2);
    this.label.string = day + '/' + month + '/' + year + '\n' + hours + ':' + minutes + ':' + seconds;
    this.lastSeconds = rawSeconds;
}

사소하지만 최적화를 신경쓴다면, 시간 UI를 매 프레임마다가 아닌 1초마다 갱신하도록 수정할 수 있다.

 

today에서 현재 시간 UI에서 가장 작은 단위인 '초(Seconds)'만 먼저 얻어낸 뒤,

 

이전 업데이트때 갱신했던 값(this.lastSeconds)과 비교하고

 

둘이 같은 값이면 갱신해봤자 같은 시간 문자열이 나오므로 리턴시킨다.

 

 

 

2. UTC

 

update(dt:number){
    let today = new Date();
    let year = today.getUTCFullYear();
    let month = ('0' + (today.getUTCMonth() + 1)).slice(-2);
    let day = ('0' + today.getUTCDate()).slice(-2);
    let hours = ('0' + today.getUTCHours()).slice(-2); 
    let minutes = ('0' + today.getUTCMinutes()).slice(-2);
    let seconds = ('0' + today.getUTCSeconds()).slice(-2);
    this.label.string = day + '/' + month + '/' + year + '\n' + hours + ':' + minutes + ':' + seconds;
}

각각의 get 함수는 UTC 시간으로 변환하는 함수가 존재한다.

 

즉 getUTCHours는 UCT+0의 시간을, getHours는 디바이스가 속한 지역(대한민국)의 UTC+@ 시간을 리턴한다.

 

대한민국은 UTC+9:00 이다.

 

 

 

3. 서버 타임

 

onLoad(){
    this.label = this.node.getChildByName("label").getComponent(cc.Label);
    this.InitSeverTime();
}

InitSeverTime(){
    if (window.XMLHttpRequest) this.xml_http_request = new XMLHttpRequest();
    else return;
}

GetServerTime():any{
    this.xml_http_request.open('HEAD', window.location.href.toString(), false);
    this.xml_http_request.setRequestHeader("ContentType", "text/html");        
    this.xml_http_request.send('');
    return this.xml_http_request.getResponseHeader("Date");
}

update(dt:number){
    let today = new Date(this.GetServerTime());
    let year = today.getUTCFullYear();
    let month = ('0' + (today.getUTCMonth() + 1)).slice(-2);
    let day = ('0' + today.getUTCDate()).slice(-2);
    let hours = ('0' + today.getUTCHours()).slice(-2); 
    let minutes = ('0' + today.getUTCMinutes()).slice(-2);
    let seconds = ('0' + today.getUTCSeconds()).slice(-2);
    this.label.string = day + '/' + month + '/' + year + '\n' + hours + ':' + minutes + ':' + seconds;
}

new Date의 매개변수로 서버에 시간 값 요청 결과를 전달하면 서버 시간을 출력할 수 있다.

 

이 경우 디바이스의 시간을 조작하더라도 정확한 시간을 출력할 수 있다.

 

 

 

 

 

 

 

위는 로컬 타임(new Date()), 아래는 서버 타임(new Date(this.GetServerTime()) 이다.

 

매 프레임마다 서버와 데이터를 주고받다 보니 Frame time과 Game Logic 시간이 크게 증가한 것을 비교할 수 있다.

 

PC에서는 차이가 느껴지지 않지만 모바일 브라우저로 실행 시 프레임이 떨어지는 현상을 겪을 수 있다.

 

시간을 초 단위까지만 출력하니까 매 프레임마다가 아닌, 매 초마다 서버에 시간 값을 요청하도록 update문에서 조건을 걸어줄 수 있다.

 

하지만 이 경우에도 모바일에서 프레임이 떨어지는 현상은 여전할 가능성이 높다.

 

최초에 1회, 그 이후에는 정해진 시간(예를 들어 1분이나 5분)마다 서버에 시간 값을 요청하고

 

그동안에는 가장 최근에 서버로부터 받은 시간 값에 로컬 시간 값을 더해주면서 계산하는 방법을 연구해야 한다.