前々回の記事で動かしたサンプルを参考に、実績とリーダーボードが実装されていない別のサンプルにこの二つを組み込んでみましょう。
今回はゲーム要素のある「ButtonClicker」を使用します。
実績とリーダーボードの閲覧
まずはactivity_main.xmlに実績閲覧用とリーダーボード閲覧用の二つのボタンを実装します。
style="@style/MainScreenButton"
android:text="実績を見る"/>
<Button android:id="@+id/showLeaderboards"
style="@style/MainScreenButton"
android:text="ランキングを見る"/>
次に、MainActivity.javaで追加したボタンを有効化します。
以下のように上記で記述したボタンを追加しましょう。
R.id.button_accept_popup_invitation, R.id.button_invite_players,
R.id.button_quick_game, R.id.button_see_invitations, R.id.button_sign_in,
R.id.button_sign_out, R.id.button_click_me, R.id.button_single_player,
R.id.button_single_player_2,R.id.showAchirvment,R.id.showLeaderboards
};
これを追加しないとsetOnClickListenerが生成されず、ボタンを押しても反応しなくなります。
もちろんボタン毎にsetOnClickListenerを記述しても良いのですが、コードが増えるので上記の方がわかりやすいかと思います。
ボタンの準備が終わったら、実績とリーダーボード、それぞれを閲覧するためのメソッドを実装します。
if (isSignedIn()) {
startActivityForResult(getGamesClient().getAchievementsIntent(), RC_UNUSED);
} else {
showAlert("サインインしてください。");
}
}
public void onShowLeaderboardsRequested() {
if (isSignedIn()) {
startActivityForResult(getGamesClient().getAllLeaderboardsIntent(), RC_UNUSED);
} else {
showAlert("サインインしてください。");
}
}
最後にonClickに上記を呼び出す記述をして完了です。
public void onClick(View v) {
switch (v.getId()) {
case R.id.showAchirvment:
resetGameVars();
onShowAchievementsRequested();
break;
case R.id.showLeaderboards:
resetGameVars();
onShowLeaderboardsRequested();
break;
}
}
これで、追加されたボタンを押すと実績とリーダーボードを閲覧できるようになります。
実績の解除とリーダーボードへの記録の送信
まずは前々回の記事と同様にアプリのリンク、実績、リーダーボードの登録を行い、ids.xmlに「TypeANumber」の同ファイルを参考にして、実績とリーダーボードのIDを記述します。
実績とリーダーボードの準備が終わったら、MainActivity.javaに以下のクラスを記述します。
int rankingScore = -1;
boolean isEmpty() {
return rankingScore < 0;
}
public void saveLocal(Context ctx) {
/* TODO: This is left as an exercise. To make it more difficult to cheat,
* this data should be stored in an encrypted file! And remember not to
* expose your encryption key (obfuscate it by building it from bits and
* pieces and/or XORing with another string, for instance). */
}
public void loadLocal(Context ctx) {
/* TODO: This is left as an exercise. Write code here that loads data
* from the file you wrote in saveLocal(). */
}
}
上記クラスの変数を宣言し、onCreateでloadLocalを実行します。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mOutbox.loadLocal(this);
}
saveLocalを行うメソッドと、リーダーボードの更新を行うメソッドを追加します。(今回はリーダーボードの名前を「ranking」としています)
if (!isSignedIn()) {
// can't push to the cloud, so save locally
mOutbox.saveLocal(this);
return;
}
if(mOutbox.rankingScore >= 0){
getGamesClient().submitScore(getString(R.string.ranking),
mOutbox.rankingScore);
mOutbox.rankingScore = -1;
}
mOutbox.saveLocal(this);
}
if(mOutbox.rankingScore < finalScore){
mOutbox.rankingScore = finalScore;
}
}
まずはクリックした回数をリーダーボードに記録するために、制限時間終了後にリーダーボードへの記録の送信を行います。
gameTick()で制限時間の管理をしているので、そこに追記します。
void gameTick() {
if (mSecondsLeft > 0)
--mSecondsLeft;
// update countdown
((TextView) findViewById(R.id.countdown)).setText("0:" +
(mSecondsLeft < 10 ? "0" : "") + String.valueOf(mSecondsLeft));
if (mSecondsLeft <= 0) {
// finish game
findViewById(R.id.button_click_me).setVisibility(View.GONE);
broadcastScore(true);
updateLeaderboards(mScore);
pushAccomplishments();
}
}
これで制限時間終了後、リーダーボードに記録がされるようになりました。
続けて、条件を満たした時に実績を解除する記述です。今回はボタンのクリックを1回目と10回目に実績を解除するように設定しています。
scoreOnePoint()でクリックした回数を管理しているので、そこに追記します。
void scoreOnePoint() {
if (mSecondsLeft <= 0)
return; // too late!
++mScore;
updateScoreDisplay();
updatePeerScoresDisplay();
if(mScore == 1){
if (getGamesClient().isConnected()) {
// unlock the "Trivial Victory" achievement.
getGamesClient().unlockAchievement(
getString(R.string.bc_achievement_1));
}
}
if(mScore == 10){
if (getGamesClient().isConnected()) {
// unlock the "Trivial Victory" achievement.
getGamesClient().unlockAchievement(
getString(R.string.bc_achievement_2));
}
}
// broadcast our new score to our peers
broadcastScore(false);
}
これでボタンクリック1回目と10回目に対応した実績が解除されるようになりました。
元のサンプルでは実績解除時にToastが表示されるようになっていますが、デフォルトで画面上部に通知が出るので今回は特に通知は行っていません。