이번에는 게임 기획을 해볼 것이다.
게임 장르는 다양하다. 액션, 어드벤처, 롤 플레잉(RPG), 시뮬레이션, 전략(RTS), 스포츠, 레이싱, 퍼즐, 호러, 음악/리듬...
이중 이번에 만들어 볼 장르는 "점핑 액션 게임" 이다.
다른 말로는 플랫폼 게임이라고 하는데, 대표적인 작품으로는 슈퍼 마리오, 별의 커비가 있다.
두 게임을 살펴보면, 일단 측면에서 보는 게임이다. 즉, 사이브뷰 게임이다.
이러한 게임은 보통 좌에서 우로 게임이 진행된다. 또한 단조롭지 않은 진행을 위해 대부분 플랫폼(발판)이 존재한다.
이러한 것들을 레퍼런스 삼아 컨텐츠를 뽑아볼 것이다.
먼저, 스테이지가 존재한다.
시간에 따라 점수를 획득할 것이고, 따라서 오래 버틸수록 높은 점수를 획득할 수 있다.
또한 스테이지가 존재하는 만큼 스테이지에 따라 얻는 점수가 달라질 것이다. 1스테이지는 1점, 2스테이지는 2점을 얻는 식으로 말이다.
다음은 아이템이 존재한다.
아이템 종류에 따라 다른 점수를 획득할 수 있고, 이는 무작위로 생성된다.
또한 스테이지에 따라 생성되는 아이템이 달라진다. 1스테이지에서는 1번 아이템만, 2스테이지에서는 1, 2번 아이템이 랜덤하게 나온다.
이렇게 컨텐츠를 뽑았으면 다음은 데이터 테이블이 필요하다
보통 아이템 같은 것들은 개발자가 아닌, 기획 쪽에서 데이터가 생성된다. 이를 관리하는 방법에는 여러가지가 있지만, 이번에는 표로 만든 다음에 JSON 파일을 관리해 볼 것이다.
먼저, 스테이지 데이터 테이블이다.
아래 테이블처럼 보통 데이터 타입을 테이블에 다 지정을 해주는데, 왜냐하면 데이터 타입에 따라 서버에서 처리하는 방식이 달라질 수 있기 때문이다.
그리고 #으로 시작하는 건 기획 관리용 이름이라는 뜻으로, 해당 컬럼은 데이터화 시키는 게 아니라는 걸 알려준다.
위의 스테이지 데이터 테이블을 JSON 파일로 바꾸면 다음과 같다.
{
"name": "stage", // 테이블 이름
"version": "1.0.0", // 테이블 버전
"data": [
{ "id": 1000, "score": 0 },
{ "id": 1001, "score": 100 },
{ "id": 1002, "score": 200 },
{ "id": 1003, "score": 300 },
{ "id": 1004, "score": 400 },
{ "id": 1005, "score": 500 },
{ "id": 1006, "score": 600 }
]
}
{
"name": "item",
"version": "1.0.0",
"data": [
{ "id": 1, "score": 10 },
{ "id": 2, "score": 20 },
{ "id": 3, "score": 30 },
{ "id": 4, "score": 40 },
{ "id": 5, "score": 50 },
{ "id": 6, "score": 60 }
]
}
그런데 아이템의 경우, 1스테이지에서 나왔던 것이 2스테이지에서도 나와야 한다.
그러나 이걸 아이템 테이블에 넣으면 정규화에 어긋난다. 따라서, 아이템이 어느 구간에서 해금되는지 따로 데이터 테이블을 만들 것이다.
아래 테이블을 보면 STAGE_ID 1001 부터 ITEM_ID 1 획득 가능하고, STAGE_ID 1002 부터 ITEM_ID 2 획득 가능하다.
또한 아무리 테이블 성질이 다르다해도, ID는 안 겹치게 하는 것이 좋다.
{
"name": "item_unlock",
"version": "1.0.0",
"data": [
{ "id": 101, "stage_id": 1001, "item_id": 1 },
{ "id": 201, "stage_id": 1002, "item_id": 2 }
]
}
이전에 API 구현에 앞서, API 명세서를 작성했다.
실시간 통신도 마찬가지다. 패킷 교환할 때도 이러한 계획서가 필요하다. 이를 패킷 구조 설계라고 한다.
이를 위해서 먼저, 공통 부분을 정한다.
여기서 handlerID, userID, clientVersion은 메시지를 보낼 때 항상 포함시켜야 한다.
예를 들어, 스테이지를 이동한다고 했을 때, 1에서 2, 2에서 3으로 이동할 것이다. 그렇다면 이를 이렇게 주고 받게 된다.
{
// 공통 부분
handlerId: 0,
userId: 0,
clientVersion: "1.0.0",
payload: {
// 스테이지 정보
currentStage: 0, // 현재 스테이지
targetStage: 0, // 이동하는 스테이지
}
}
아이템 획득도 다음과 같다.
{
// 공통 부분
handlerId: 0,
userId: 0,
clientVersion: "1.0.0",
payload: {
// 아이템 정보
itemId: 0,
}
}
마지막으로 생각해야할 건, 이렇게 메시지를 받고 데이터를 처리했다면, 이제 서버가 결과값을 보내줘야 한다.
이때, 서버가 유저에게 뭔가 주는 건 없지만, 대신 처리가 제대로 끝났다는 Response는 해야한다.
'프로젝트' 카테고리의 다른 글
24/09/29 - [실습] 점핑 액션 게임(3): UUID와 유저 접속 관리 (1) | 2024.09.29 |
---|---|
24/09/27 - [실습] 점핑 액션 게임(2): 환경 설정, 데이터 테이블(feat. FS 모듈) (0) | 2024.09.27 |
24/09/25 - [팀] 풋살 온라인(4): 최종 회고 (0) | 2024.09.25 |
24/09/24 - [팀] 풋살 온라인(3): 보유한 선수 목록 & 랭킹 조회 (0) | 2024.09.24 |
24/09/23 - [팀] 풋살 온라인(2): 문제점 수정과 Promise.all/Promise.allSettled (0) | 2024.09.23 |