스테이지 넘어가기
크롬 dino 게임을 모방하여 하는 개인과제를 진행중
필수과제중 내가 구상한 스테이지를 바탕으로 플레이어의 Score가 100점이 넘어갈때마다 다음 스테이지로 넘어가게 하는 기능을 구현해야 한다.
기본적으로
서버 코드
// 점수 검증
const serverTime = Date.now();
const elapsedTime = (serverTime - currentStage.timestamp) / 1000; // 초 단위로 계산
// 1초당 1점, 100점이상 다음스테이지 이동, 오차범위 5
// 클라이언트와 서버 간의 통신 지연시간을 고려해서 오차범위 설정
// elapsedTime 은 100 이상 105 이하 일 경우만 통과
if (elapsedTime < 100 || elapsedTime > 105) {
return { status: 'fail', message: 'Invalid elapsed time' };
}
클라이언트 코드
stageChange = true;
...
update(deltaTime) {
this.score += deltaTime * 0.001;
// 점수가 100점 이상이 될 시 서버에 메세지 전송
if (Math.floor(this.score) === 100 && this.stageChange) {
this.stageChange = false;
sendEvent(11, { currentStage: 1000, targetStage: 1001 });
}
}
플레이어가 게임을 시작한 시간과 게임이 끝난 시간을 구해서 (게임이 끝난시간 - 게임이 시작한 시간) 이 플레이어의 점수이고 그 점수가 100보다 크고 105보다 작을 경우에만 다음 로직으로 넘어갈 수 있도록 되어있다.
하지만 분명 이런 방식으로하자 deltaTime의 수치에 *0.001이 아닌 0.01 ▲이상의 수치를 입력하면 Invalid 에러가 뜨는 현상을 해결하지 못했다.
이런식으로는 내가 구상했던 방식으로는 구현이 될것 같지않았기에 다른 방법으로 검증을 하기로했다.
클라이언트에서 게임 종료시점의 score를 함께 서버로 보내주어 그 값을 기준으로 검증하도록 수정
if (payload.clientTime > 100 || payload.clientTime < 105) {
return { status: "fail", message: "시간 초과" };
}
이런 방식으로 하자 스테이지 1000에서 스테이지 1001로 넘어가는건 문제없이 다음 로직으로 넘어가진다.
하지만 지금 작성된 코드는 score가 100점이 된 경우에만 다음 스테이지로 넘어가기때문에 점수가 200 300 400이 될 경우에는 아무런 반응을 하지않는다.
기존 구상은 모든 스테이지가 끝날때까지 유저가 특정 score을 달성한다면 다음 스테이지로 넘어가야한다.
그렇다면 어떻게 해줘야할까
1.currentStage의 값이 유저의 score가 특정 값에 도달할경우 1씩 올라가도록 해주어야한다.
2.유저의 score가 100에서 끝나는게 아닌 특정값에 도달할 때마다 실행되도록 해줘야한다.
3.유저의 점수의 검증또한 100~105만 검증하는것이아닌 특정 조건을 만족할때마다 검증이 가능해야한다.
일단 currentStage의 기본값을 Score클래스의 전역변수로 정의한다.
유저의 score가 100점일 경우 실행 하는것이아닌 유저가 100점에 도달할 때마다 실행해 줘야함으로
score % 100 ===0 이 될 경우에 실행되도록 수정
이렇게 작성할경우 유저의 현재 점수가 100으로 나누어 떨어질 경우마다 실행된다.
아래의 코드는 현재 유저의 score가 100으로 나누어 떨어지고 stageChange가 true일 경우
stageChange의 값을 false로 바꾸고 sendEvent를 실행한다.
현재 스테이지의 값이 currentStage의 값으로 할당되고 다음스테이지 targetStage는 현재 스테이지의 +1 의 값으로 할당해주어 다음 스테이지 로 넘어간다.
그리고 점수 검증을 위해 score를 서버로 함께 보내준다.
클라이언트 코드
class Score {
score = 0;
HIGH_SCORE_KEY = "highScore";
stageChange = true;
currentStage = 1000;
constructor(ctx, scaleRatio) {
this.ctx = ctx;
this.canvas = ctx.canvas;
this.scaleRatio = scaleRatio;
}
update(deltaTime) {
this.score += deltaTime * 0.01;
if (Math.floor(this.score) % 100 === 0 && this.stageChange) {
this.stageChange = false;
console.log("현재 스테이지:", this.currentStage);
sendEvent(11, {
currentStage: this.currentStage,
targetStage: this.currentStage + 1,
clientTime: this.score,
});
하지만 이렇게 작성한다면 stageChange가 false로 고정되어 한번만 다음스테이지로 넘어가며
다음 스테이지로 넘어갔을 경우 그 다음 스테이지의 값이 들어오지않는다.
이를 해결하기위해 조건을 추가해주었다.
this.currentStage += 1;
}
if (Math.floor(this.score) % 100 !== 0) {
this.stageChange = true;
}
score % 100 ===0 이며 stageChange가 false라면 sendEvent를 실행하고 currentStage에 1을 더한다.
이후 score % 100 !==0 라면 stageCjange의 값을 true로 변경하여 다시 처음으로 돌아간다.
이제 서버에서도 클라이언트에서 보내준 score를 사용해 점수 검증을 해준다.
if (payload.clientTime % 100 === 0) {
return { status: "fail", message: "시간 초과" };
}
이렇게 검증까지 통과한다면
위 사진처럼 score가 100점이 넘어갈때마다 다음 스테이지로 넘어가고 currentStage의 값이 게임에셋에 있는 데이터와 일치하지않는다면 fail을 반환한다.
'부트캠프' 카테고리의 다른 글
webSocket_Project 마무리 (7) | 2024.10.07 |
---|---|
webSocket_Project_2 (0) | 2024.10.02 |
Nalgangdoo_Project 5일차 (1) | 2024.09.24 |
Nalgangdoo_Project 4일차 (0) | 2024.09.23 |
Nalgangdoo_Project 3일차 (0) | 2024.09.20 |