کار با لیدربورد - Android
در این مستند ما نحوه ساخت رویداد (Event) و ارسال آن به سرور و دیدن نتیجهی آن در لیدربوردهای اپلیکیشن را خواهیم دید.
پیشنیازها
- در صورتی که با سرویس مرکز بازی آشنایی ندارید، به معرفی سرویس مرکز بازی مراجعه کنید.
- در صورتی که هنوز در پنل توسعهدهنده خود تنظیمات لازم برای مرکز بازی را انجام ندادهاید، به تنظیمات پنل مراجعه کنید.
- در صورتی که هنوز SDK اندروید را راهاندازی نکردهاید، به راهاندازی SDK بکتوری در اندروید مراجعه کنید.
راهاندازی سرویس مرکز بازی
پس از راهاندازی SDK بکتوری در اندروید، در شروع اپلیکیشن بایستی SDK بکتوری را initialize کنید. در عمل initialize، شما تمامی سرویسهایی که علاقمند به استفاده هستید را ذکر خواهید کرد. برای سرویس مرکزبازی کدی مشابه زیر بایستی داشته باشید:
// Extending android application to initialize backtory
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Initializing backtory
BacktoryClient.init(KeyConfiguration.newBuilder().
setAuthKeys("<X-Backtory-Authentication-Id>",
"<X-Backtory-Authentication-Key (Client)>").
// Enabling Game Center
setGameKey("<X-Backtory-Game-Id>").
// Finalizing sdk
build(), this);
}
}
ارسال یک رویداد (Event)
همانطور که در بالا گفتیم، با ارسال رویداد تغییرات لازم در لیدربورد اعمال میشوند و امتیاز بازیکنها و رتبهی آنها بهروز میشود. برای ارسال یک رویداد میتوانید از یکی از دو روش زیر استفاده کنید:
1. استفاده از لیست مقادیر
در این روش شما لیستی از key-valueها تولید کرده و به عنوان دادهی رویداد، به تابع ارسال یک رویداد، پاس میدهید. کد زیر نمونهای از این روش میباشد:
// Step 1: Creating parameters for GameOver event
List<FieldValue> fieldValues = Arrays.asList(
new FieldValue("gold", 100),
new FieldValue("time", 200));
// Step 2: Creating GameOver event and filling its data
BacktoryEvent event = new BacktoryEvent();
event.setName("GameOver");
event.setFieldsAndValues(fieldValues);
// Step 3: Sending event to server
event.sendInBackground(new BacktoryCallBack<Void>() {
// Checking callback from server
@Override
public void onResponse(BacktoryResponse<Void> response) {
if (response.isSuccessful()) { // = Event saved to server successfully
Log.d("TAG", "saved event successfully");
} else {
// do something based on response.code()
}
}
});
همانطور که در درخواست بالا میبینید ما یک رخداد GameOver با زمان ۲۰۰ و طلای ۱۰۰ ارسال کردیم. در صورتی که تمایلی به انجام کاری در callback ندارید، کافیست آن را null پاس بدهید. یعنی:
event.sendInBackground(null);
2. استفاده از یک شیء جدید
در صورتی که مدل لیست مقادیر key-value را نمیپسندید و دوست دارید کمی شیءگراتر (Object-Oriented) باشید میتوانید کلاس BacktoryEvent بکتوری را گسترش (Extend) دهید، منطق مورد نظر خود را به آن اضافه کنید و توابع سازنده (Constructor) دلخواه جهت سهولت استفاده به آن اضافه کنید.
برای مثال رخداد GameOver در مثال قبل به شکل زیر خواهد بود:
public class GameOverEvent extends BacktoryEvent {
@EventName
public static final String eventName = "GameOver";
@FieldName("gold")
int goldValue;
@FieldName("time")
int timeValue;
public GameOverEvent(int goldValue, int timeValue) {
this.goldValue = goldValue;
this.timeValue = timeValue;
}
}
همانطور که میبینید چند annotation بر روی خصوصیات کلاس، یک کد زیباتر و شکیلتر معادل با کد روش اول، تولید میکند. این annotationها عبارتند از:
- EventName@: نام رخداد که همان GameOver است، را مشخص میکند.
- FieldName@: مشخص میکند که یک خصوصیت در این کلاس جزء مواردی که باید به سرور بکتوری ارسال شود، هست یا خیر. در کد بالا دو فیلد goldValue و timeValue به ترتیب به عنوان gold و time به سرور ارسال خواهند شد.
ارسال این رخداد مانند روش اول خواهد بود، زیرا رخداد GameOverEvent فرزند BacktoryEvent است و توابع آن را به ارث میبرد. پس کد زیر کار ارسال را انجام خواهد داد:
// Step 1 & 2: Create event and fill it
GameOverEvent event = new GameOverEvent(100, 200);
// Step 3: send it
event.sendInBackground(new BacktoryCallBack<Void>() {
@Override
public void onResponse(BacktoryResponse<Void> response) {
if (response.isSuccessful()) { // = Event saved to server successfully
Log.d("TAG", "saved event successfully");
} else {
// do something based on response.code()
}
}
});
بروز خطا
در صورت بروز خطا در ارسال رخداد عبارت ()response.isSuccessful برابر false خواهد بود، و ()response.code نوع خطا را مشخص میکند که یکی از مقادیر زیر است:
Tables | Description |
---|---|
417-Incorrect event data | Event data is incorrect |
400-Bad Request | EventName or fieldName is null |
500-Internal Server Error | Data access was unsuccessful |
503-Service Unavailable | Backtory is unavailable right now |
ساخت شیء لیدربورد در SDK
برای آنکه بتوانید به یک لیدربورد در بکتوری اتصال پیدا کنید و اطلاعات آن را از سرور دریافت کنید، باید از کلاس BacktoryLeaderBoard در SDK استفاده کنید.
برای ساخت لیدربورد دو روش دارید:
۱. یک شیء از کلاس BacktoryLeaderBoard ساخته و شناسه لیدربورد را به آن پاس دهید. به صورت زیر:
BacktoryLeaderBoard topPlayers = new BacktoryLeaderBoard("576d4a33e4b050913524162c");
۲. کلاس BacktoryLeaderBoard را گسترش دهید. مانند زیر:
public class TopPlayersLeaderBoard extends BacktoryLeaderBoard {
@LeaderBoardId
public static final String id = "576d4a33e4b050913524162c";
}
و هر جا که لازم بود از آن یک نمونه به صورت زیر بسازید:
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();
در هر یک از دو صورت بالا شما میتوانید سه عمل مهم با لیدربورد انجام دهید:
- گرفتن رتبه کاربری که در اپلیکیشن شما وارد شده است. (My score)
- گرفتن نفرات بالای لیدربورد (Top of leaderboard)
- گرفتن نفرات اطراف کاربر فعلی در لیدربورد (Around me)
رتبه یک بازیکن در لیدربورد
توجه: این سرویس تنها برای کاربر فعلی گوشی کاربرد دارد و امکان گرفته رتبه سایر بازیکنان در SDK، به خاطر مسئله امنیت، وجود ندارد. در صورتی که نیازمند به گرفتن رتبه دیگران هستید، باید از سرویس رایانش استفاده کنید.
برای آنکه بتوانید رتبه کاربری که از طریق سرویس کاربران در اپلیکیشن شما ورود انجام داده است، را دریافت کنید، کافیست لیدربورد مورد نظر خود را بسازید و تابع getPlayerRankInBackground را فراخوانی کنید:
// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();
// Get your loggedIn user's rank in topPlayers
topPlayers.getPlayerRankInBackground(new BacktoryCallBack<LeaderBoardRank>() {
// Callback from server
@Override
public void onResponse(BacktoryResponse<LeaderBoardRank> response) {
// Check if backtory returned result successfully
if (response.isSuccessful()) {
// Extract response info
String leaderboardPosition = "my rank: " + response.body().getRank()
+ "\n my scores: " + response.body().getScores();
// Log it
Log.d("TAG", leaderboardPosition);
} else {
// do something based on error code
}
}
});
در صورتی که عبارت ()response.isSuccessful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت ()response.code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:
Tables | Description |
---|---|
200-OK | Successful |
417-Incorrect data | Something is incorrect in leaderboard |
400-Bad Request | LeaderboardId is null or invalid |
500-Internal Server Error | Data access was unsuccessful |
503-Service Unavailable | Backtory is unavailable right now |
نفرات برتر در لیدربورد
معمولا مهمترین نیاز در لیدربورد این است که شما بتوانید آن را در اپلیکیشن خود نشان دهید. و معمولا منظور از نشان دادن لیدربورد نیز آن است که مثلا ۱۰۰ نفر برتر اپلیکیشن خود را در معرض دید قرار دهید، تا کاربران تشویق به بازی بیشتر و قرار گرفتن جز این نفرات شوند. برای آنکه بتوانید ۱۰۰ نفر بالای لیدربورد خود را از سرور دریافت کنید، باید کدی مانند زیر را اجرا کنید:
// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();
// Request for top 100 to backtory
topPlayers.getTopPlayersInBackground(100, new BacktoryCallBack<LeaderBoardResponse>() {
// Check server response
@Override
public void onResponse(BacktoryResponse<LeaderBoardResponse> response) {
// Checking if response was fetched successfully
if (response.isSuccessful()) {
// Getting first person (Number 1) in leaderboard
UserProfile topPlayer = response.body().getUsersProfile().get(0);
String username = topPlayer.getUserBriefProfile().getUserName();
List<Integer> scores = topPlayer.getScores();
// Logging the best player
Log.d(TAG, "best player is: " + username
+ "\n scoring: " + scores);
} else {
// do something based on error code
}
}
});
توجه: محدودیت تعداد نفرات بالای لیدربورد ۱۰۰ است و اگر شما برای بیش از این تعداد درخواست دهید، با خطا مواجه خواهید شد.
در صورتی که عبارت ()response.isSuccessful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت ()response.code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:
Tables | Description |
---|---|
200-OK | Successful |
417-Incorrect data | Something is incorrect in leaderboard |
400-Bad Request | LeaderboardId is null or invalid |
500-Internal Server Error | Data access was unsuccessful |
503-Service Unavailable | Backtory is unavailable right now |
اطرافیان من در لیدربورد
یکی از المانهای اپلیکیشن که برای کاربران جذاب است این است که بدانند در لیدربورد بازی رتبه چندم را دارا هستند و اختلافشان با اطرافیان چقدر است. به این ترتیب میتوانند میزان زمانی که باید صرف بازی کنند و نتیجهای که در لیدربورد آنها خواهد داشت را تخمین زده و به بازی بپردازند. به این عمل Around-me گفته میشود.
در صورتی که میخواهید ۵ نفر بالا و ۵ نفر پایین خود را دریافت کنید باید به تابع Around-me عدد ۱۰ را پاس بدهید. بکتوری در جواب یک آرایه حداکثر به طول ۱۱ برمیگرداند که شامل ۵ نفر بالا، کاربر شما و ۵ نفر پایین خواهد بود. دقت کنید که در صورتی که کاربر شما در شرایط مرزی باشد، برای مثال نفر اول لیدربورد باشد، ۵ نفر بالا برایش معنی ندارد و جواب یک آرایه به طول ۶ خواهد بود که شامل کاربر فعلی در صدر و ۵ کاربر پایین او خواهد شد.
کد زیر یک درخواست ساده برای دریافت اطلاعات ۱ نفر بالا و ۱ نفر پایین را به سرور بکتوری میدهد:
// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();
// Request for 2 players which are around me is TopPlayers leaderboard,
// Normally, index 0 is above me, index 1 is ME, and index 2 is below me
topPlayers.getPlayersAroundMeInBackground(2,
new BacktoryCallBack<LeaderBoardResponse>() {
// Checking server response
@Override
public void onResponse(BacktoryResponse<LeaderBoardResponse> response) {
if (response.isSuccessful()) { // = result is valid
// Get above and below players
UserProfile aboveMePlayer = response.body().getUsersProfile().get(0);
UserProfile belowMePlayer = response.body().getUsersProfile().get(2);
// Logging result
Log.d(TAG, "you are behind "
+ aboveMePlayer.getUserBriefProfile().getUserName()
+ "\n but better than "
+ belowMePlayer.getUserBriefProfile().getUserName());
} else {
// do something based on error code
}
}
});
در مثال بالا عدد ۲ بدین معنی است که میخواهید ۱ نفر بالا و ۱ نفر پایین کاربر فعلی را دریافت کنید. محدودیت تعداد اطرافیانی که بکتوری در اختیار شما میگذارید، عدد ۲۰ است (یعنی ۱۰ نفر بالا و ۱۰ نفر پایین) و اگر عدد بالاتری را درخواست کنید، با خطا مواجه خواهید شد.
در صورتی که عبارت ()response.isSuccessful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت ()response.code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:
Tables | Description |
---|---|
200-OK | Successful |
417-Incorrect data | Something is incorrect in leaderboard |
400-Bad Request | LeaderboardId is null or invalid |
500-Internal Server Error | Data access was unsuccessful |
503-Service Unavailable | Backtory is unavailable right now |