-
Notifications
You must be signed in to change notification settings - Fork 0
Guide
#Hive5 v5 Guide
- 본 문서는 확정된 상태가 아니라 수정중에 있습니다.
- REST API가 정확하게 표현되지 않은 상태이므로, 개요를 파악하는 수준으로 활용하세요.
##Introduction 본 문서는 Hive5를 쉽게 개괄할 수 있도록 애니팡과 같은 간단한 게임의 개발을 가정하고, 필요한 요소와 작업들을 기술했습니다. 과정들을 따라가면서 다음과 같은 내용들에 알 수 있게 됩니다.
- 로그인과 Social 링킹 얻기
- 게임의 시작과 종료, 스코어 등 사용자 정보 저장
- 아이템의 구매와 사용
- 결제 처리와 아이템 충전
- 미션과 보상
- Push
##1. 로그인과 Social 랭킹
먼저 관리콘솔에서 신규 게임을 생성합니다. 게임을 생성하면, App Access Key가 발급됩니다. REST API 호출의 인증에는 3개의 헤더 X-APP-KEY, X-AUTH_UUID, X-AUTH-TOKEN가 필요합니다. X-APP-KEY가 App Access Key에 해당합니다. (X-AUTH-TOKEN은 이후에서 언급하게 될 로그인의 결과로 얻어옵니다.)
이제 본격적으로 애니팡 스타일의 게임을 만들어 보겠습니다. 소셜 플랫폼으로는 카카오를 선택하겠습니다. 이 외에도 Hive5에는 페이스북, 구글, 네이버, 익명 로그인을 제공합니다. 익명 로그인은 별도의 소셜 플랫폼이 없는 형태입니다.
카카오의 경우 개발사와 카카오 간의 계약이 선행되어야 합니다. 계약 이후에 카카오 API를 호출할 수 있는 key 등을 발급받게 됩니다. 페이스북이나 구글의 경우는 이와 달리 웹상에서 바로 앱을 생성해서 key를 발급받아 해당 플랫폼의 API를 호출할 수 있습니다.
이제 게임 화면을 구성합니다. 게임을 실행하면 먼저 로그인을 해야 합니다. 카카오 로그인을 해보겠습니다.
로그인 버튼을 누르면, 우선 카카오 API를 통해 로그인을 수행합니다. 이때 아이디와 친구목록도 받게 됩니다. 자세한 내용은 카카오 API 문서를 참조해주세요. 보통 아래와 같은 형태로 로그인을 수행합니다.
[카카오 로그인 api call]
카카오에 로그인에 성공했으면 Hive5에도 로그인과 친구목록 업데이트를 수행해야 합니다. 그렇게 해야 Hive5에서 데이터들이 유지되고 이 데이터들을 이용해서 통계 분석이나 리더보드 업데이트가 이루어집니다.
로그인은 다음과 같이 호출합니다. 본 문서에서는 REST API로 표현했으나, Unity용 SDK를 사용하시면 관련된 함수 호출을 수행하시면 됩니다.
GET http://hornet.hive5.io/v5/auth/login?platform=kakao&platform_user_id=3432983
최초로 로그인을 하는 경우라면 이 때 사용자가 생성됩니다. 로그인에 성공하면 결과값이 리턴됩니다. 결과 값에는 다양한 데이터들이 있습니다. 이 중 access_token은 향후 API 호출에 반드시 필요하니, 잘 저장해 두어야 합니다.
이제 스코어나, 하트 개수 등 사용자의 정보를 얻어올 차례입니다. 신규 플레이어라면 이런 정보들을 디폴트로 저장해야 합니다. 이를 위해 프로시저를 사용합니다. 프로시저는 javascript 기반으로 콘솔에서 미리 등록시킵니다. 그리고 클라이언트에서 호출을 하면, 서버에서 실행되는 구조입니다. 프로시저를 통해 데이터를 불러오거나 저장할 수 있으며, 미리 정의된 테이블을 참조해서 비교 판단할 수 있습니다. 그 외에도 Hive5에서 제공하는 메일이나, 리더보드 등의 기능에 대해 제어가 가능합니다. 프로시저에 대한 자세한 내용은 Procedure 문서를 참조하세요. 지금은 Hive5 object를 이용해서 플레이어 정보를 초기화하는 get_player_info라는 프로시저를 다음과 같이 만들어 보겠습니다.
function get_player_info(params) {
// 최초 로그인인 경우 player를 초기화한다. 플레이어 정보를 리턴받는다.
player = HObject.load("player"); //singleton으로 player라는 클래스 이름의 객체를 얻어온다.
if (player.level == null) { // level 필드가 정의되지 않았으면, 최초 사용자이므로, 초기화하여 저장한다.
//각종 필드 초기화
player.level = 1;
player.exp = 0;
player.score = 0;
player.highscore = 0;
player.ruby = 5;
player.coin = 500;
player.items = new Array();
HObject.save(player);
}
return player;
}이 프로시저를 호출하는 API는 다음과 같습니다. 로그인의 결과로 획득한 access token도 헤더에 추가해야 합니다.
GET http://hornet.hive5.io/v5/procedures/call/get_player_info
이 프로시저의 호출 결과로 플레이어의 레벨, 점수, 코인과 루비 수 등을 받아오게 되므로, 클라이언트에서 적절하게 표시합니다.
player라는 클래스 이름의 싱글턴 객체가 있는 건데 여기에 다른 어떤 정보도 저장하거나 업데이트 할 수 있습니다. 물론 프로시저를 통해 값을 추가하거나 변경할 수 있지만, Object를 생성하거나, 읽어오거나, 저장하는 API도 존재합니다. Objects API를 참조해주세요.
로그인까지 성공했으면 그 다음 화면은 보통 친구 목록과 순위가 표시됩니다.
친구 목록은 카카오 로그인 API에서 얻어왔는데, 이 친구 목록은 hive5에도 동일하게 유지를 시켜주어야 하기 때문에 hive5 API를 이용해서 아래와 같이 갱신시켜주어야 합니다. request body에 JSON 형식으로 친구들의 platform user id를 넘기게 됩니다.
POST http://hornet.hive5.io/v5/friends/update
친구들 간의 순위가 social 랭킹입니다. social 랭킹을 얻어오기 위해서는 우선 리더보드를 관리콘솔에서 생성합니다. 그리고 생성된 리더보드 id를 이용해서 다음과 같이 호출합니다.
GET http://hornet.hive5.io/v5/leaderboards/1/social_scores
이제 social 랭킹을 얻어왔기 때문에 클라이언트에서 순위에 관련된 부분도 완성할 수 있습니다.
##2. 게임의 시작과 끝
이제 게임 시작 화면입니다. 애니팡 스타일의 게임은 시작을 위해 하트가 필요합니다. 그리고 하트는 일정시간 마다 자동으로 충전됩니다. 먼저 하트의 개수를 가져오는 check_heart 프로시저를 만들어보겠습니다. 이 프로시저에는 하트가 자동충전되는 부분도 포함되어 있습니다. inner-function을 사용했다는 점도 확인해주세요.
function check_heart(params) {
function update_heart() {
// 초기화 안된 경우 추가
if (player.heart_max==null) {
player.heart=5;
player.heart_max=5;
player.heart_recharging_interval=10*1000; // test로 10초
}
// 하트가 최대치이거나, 충전시간에 도달안됐으면 리턴
if (player.heart_max==player.heart || Date.now()<player.heart_next_recharge) {
return;
}
// 경과 시간으로 충전가능 하트 수 계산
var now = Date.now();
var elapsed_time = now - (player.heart_next_recharge - player.heart_recharging_interval);
var rechargable_heart_count = Math.floor(elapsed_time/player.heart_recharging_interval);
// 최대치 고려하여 그 수 만큼 충전
player.heart = player.heart + rechargable_heart_count;
if (player.heart > player.heart_max)
player.heart = player.heart_max;
// 다음 충전시간 갱신
if (player.heart == player.heart_max)
player.heart_next_recharge = null; // 최대치이므로, 다음 충전시간은 없음
else
player.heart_next_recharge = now + player.heart_recharging_interval - (elapsed_time % player.heart_recharging_interval);
}
var player = HObject.load("player");
update_heart(); //자동충전을 위한 업데이트 함수
HObject.save(player);
return {heart:player.heart, next_recharge:player.heart_next_recharge, now:Date.now()};
}프로시저는 다음과 같이 호출합니다. 그 결과로 현재의 하트 개수와, 다음 충전시간이 넘어오므로, 클라이언트에서도 타이머를 돌려서 충전되는 시간 효과를 낼 수 있습니다.
GET http://hornet.hive5.io/v5/procedures/call/check_heart
이제 게임 시작 버튼을 누르면 게임시 시작됩니다. 게임을 시작하면 1개의 하트가 소모되므로, 이를 위한 프로시저도 만들겠습니다. 이름을 start_game이라고 하겠습니다. 이 프로시저 내에서는 다음 하트 충전시간도 계산해서 저장합니다.
function start_game(params) {
// 하트 감소
var player=HObject.load("player");
if (player.heart==0)
throw "사용가능 하트 없음";
player.heart--;
// 다음 충전시간이 null이면 충전가능 시간을 계산해 세팅
if (player.heart_next_recharge==null) {
player.heart_next_recharge = Date.now() + player.heart_recharging_interval;
}
// save
HObject.save(player);
return {heart:player.heart, next_recharge:player.heart_next_recharge};
}프로시저 호출은 위와 동일합니다. 이제 클라이언트에서는 게임을 진행하면 됩니다.
게임이 종료되면 스코어를 산출할 수 있습니다. 이제 스코어를 파라미터로 하여 게임의 종료 처리를 수행하는 프로시저를 호출합니다. 이 프로시저에서는 스코어를 저장하고, 리더보드에도 등록하며, 각종 보상을 수행합니다. 다음은 이런 작업의 예를 보여주는 end_game 프로시저입니다. 신기록을 갱신할 경우 100코인의 보상이 지급되고 있음을 확인해 주세요.
function end_game(params) {
//params
//score: 획득한 점수
var score = parseInt(params.score);
var player = HObject.load("player");
player.score += score; //개인 점수를 누적시켜 줌.
var rewards = new Array();
// high score 를 달성했는지 확인
if (score>player.highscore) {
player.highscore = score;
// 하이스코어 달성 보상 수행
player.coin+=100;
rewards.push({name:"highscore", msg:"100코인이 지급되었습니다."});
}
HObject.save(player);
// 스코어를 리더보드에 제출
var leaderboard_id = 1;
HLeaderboard.submitScore(leaderboard_id, score);
return {player:player, rewards:rewards};
}이 프로시저는 파라미터가 필요합니다. score를 다음과 같이 query string 형식으로 넘겨서 호출합니다.
GET http://hornet.hive5.io/v5/procedures/call/end_game?score=300
##3. 아이템 구매와 사용
예제 게임에서는 루비와 코인이라는 두 종류의 화폐가 통용됩니다. 루비는 현금 결제를 통해서만 구입이 가능하며, 코인은 가입시에도 기본으로 제공되고 게임에 대한 각종 보상으로도 지급됩니다. 이번 장에서는 실제 현금 결제가 아닌 코인을 이용해서 아이템을 구매하는 경우를 다룹니다.
최초 가입시 제공되는 기본 코인과 신기록 갱신에 대한 보상으로 코인 증가시키는 법은 앞 장의 프로시저 내용에서 이미 다루었습니다.
아래는 게임 시작 직접의 아이템샵 UI입니다. 황금폭탄을 구매하면, 코인 590이 차감되고, 게임에서 이 아이템을 사용할 수 있습니다.
게임시작을 누르면 선택된 start_game 프로시저를 호출했는데, 여기에 아이템들의 구매 처리를 추가시켰습니다.
function start_game(params) {
// params
// items : 구매하려는 아이템 3개 (item no를 |로 구분)
// item table 로드
var item_tbl = HDataTable.load("item");
function getItem(no) {
for (i=0; i<item_tbl.length; i++) {
if (no == item_tbl[i].no)
return item_tbl[i];
}
return null;
}
// 하트 감소
var player=HObject.load("player");
if (player.heart==0)
throw "no heart";
player.heart--;
// 다음 충전시간이 null이면 충전가능 시간을 계산해 세팅
if (player.heart_next_recharge==null) {
player.heart_next_recharge = Date.now() + player.heart_recharging_interval;
}
// 아이템 구매
var buying_items = params.items.split("|");
if (buying_items.length>3)
throw "too many items";
for (i=0; i<buying_items.length; i++) {
var item = getItem(buying_items[i])
if (item==null)
throw "item not found.";
player.coin -= item.price;
}
if (player.coin<0)
throw "no coin.";
// save
HObject.save(player);
return "ok";
}이 프로시저는 다음과 같이 구매하려는 아이템의 고유번호를 최대 3개까지 |로 구분해서 넘깁니다.
GET http://hornet.hive5.io/v5/procedures/call/start_game?items=3|4
프로시저에서 HDataTable 라이브러리를 사용하고 있습니다. 콘솔의 Data Table에서 item이라는 아이템의 목록을 미리 정의시켜 두었고, 이를 로드한 것입니다. 다음은 아이템을 정의한 테이블의 예입니다.
| no | name | price |
|---|---|---|
| 1 | 돋보기 | 180 |
| 2 | 긴급폭탄 | 200 |
| 3 | 시간 보너스 | 270 |
| 4 | 황금폭탄 | 590 |
테이블에서 정의된 가격 만큼 사용자 코인에서 차감해서 저장했습니다. 이를 통해 아이템 구매를 처리할 수 있었으며, 남은 코인이 있는지를 비롯해서 각종 조건들도 검사할 수 있습니다. 이제 클라이언트에서는 구매한 아이템을 발동할 수 있도록 게임을 구성하면 됩니다.
아래의 화면은 토파즈를 이용해서 코인을 구매하는 UI입니다. 역시 프로시저를 이용할 수 있습니다. 구현의 예입니다. 지불하려는 ruby를 파라미터로 넘기게 됩니다.
function buy_coin(params) {
var ruby = parseInt(params.ruby);
var tbl = HDataTable.load("coin_ruby", {ruby:ruby});
if (tbl.length!=1)
throw "product not found";
var player=HObject.load("player");
player.ruby -= tbl[0].ruby;
player.coin += tbl[0].coin;
if (player.ruby<0)
throw "no ruby.";
// save
HObject.save(player);
return "ok";
}HDataTable.load 함수에서 이전의 예와는 다르게 조건을 추가해 특정 row만을 가져오게 할 수 있음을 확인해 주세요.
어떤 아이템은 1번의 게임에만 적용되지 않고, 특정시간 동안 유효하기도 합니다. 이런 아이템은 Player 정보에 기록을 해두어야 다음 로그인 때도 사용이 가능합니다. 아래와 같은 경험치 물약이 좋은 예입니다.
player의 items 필드에 필요한 정보들을 저장할 수 있습니다. 다음 프로시저가 구현 예입니다.
function buy_exp_potion(params) {
var ruby = parseInt(params.ruby);
var tbl = HDataTable.load("potion_ruby", {ruby:ruby});
if (tbl.length!=1)
throw "product not found";
var player=HObject.load("player");
player.ruby -= tbl[0].ruby;
if (player.ruby<0)
throw "no ruby.";
// 물약 아이템이 이미 있는지 조사
for (i=0; i<player.items.length; i++) {
if (player.items[i].type == "exp_potion")
throw "already possessed";
}
// 물약 아이템 추가
var potion = {type:"exp_potion"};
potion.expired = Date.now() + tbl[0].duration*1000;
player.items.push(potion);
// save
HObject.save(player);
return potion;
}물약 효과의 만기시간을 expired 필드에 저장했습니다. 이제 start_game 등에서 만기시간을 넘겼으면, 그 아이템을 삭제하는 처리를 수행하고, 유효하다면 클라이언트에서 경험치를 계산하는데 이용할 수 있을 것입니다.





