一,前期基础知识储备
1)排行榜官方文档:https://developers.google.com/games/services/common/concepts/leaderboards
Leaderboards can be a fun way to drive competition among your players, both for your most hardcore fans (who will be fighting for the top spot in a public leaderboard) and for your more casual players (who will be interested in comparing their progress to their friends').
2)成就系统官方文档:https://developers.google.com/games/services/common/concepts/achievements
Achievements can be a great way to increase your users' engagement within your game. You can implement achievements in your game to encourage players to experiment with features they might not normally use, or to approach your game with entirely different play styles.
3)实际应用中需要安装 Google Play Game游戏服务应用,打开登录谷歌账号,这样才能正常进行显示之后的内容。
4)后台同事帮忙在谷歌控制台(Google Play Console)对应用进行注册,拿到应用对应的 APP_ID,用以注册该应用,然后需要为排行榜和成就系统各自注册ID。一个排行榜对应一个ID,一个成就对应一个ID,在注册排行榜时默认需要注册5个成就,这样才能配置成功,另外在应用内成就可以选择是否进行展示。
二,上代码,具体实现
1)添加依赖:
①应用级添加依赖:
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.google.gms:google-services:4.0.1'
}
②项目级添加依赖:
// game
implementation 'com.google.android.gms:play-services-auth:16.0.0'
implementation 'com.google.android.gms:play-services-games:16.0.0'
2)Manifest中进行注册:
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/app_id" />
<meta-data android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
这里使用到的APPID,即为之前在谷歌后台注册时拿到的12位数ID。
3)下载好了GooglePlay,然后判断应用是否登录成功:
/*登录状态验证*/
private boolean isSignedIn() {
Log.d(TAG, "onAnimationEnd: onActivityResult 88,," + GoogleSignIn.getLastSignedInAccount(this));
return GoogleSignIn.getLastSignedInAccount(this) != null;
}
这里有一个关键的理论需要理顺,就是在使用排行榜和成就系统前,需要先对Google Paly账号登录的状态做一个判断。若是登录成功,则可以直接执行之后的逻辑,若是登录失败,则需要先登录账号。
4)登录 GooglePlay 账号:
/*判断是否已经登录*/
private boolean signInIfNotAlready() {
if (!isSignedIn()) {
/*未登录 则开始登录*/
signIn();
Log.d(TAG, "onAnimationEnd: onActivityResult 66");
return true;
} else {
Log.d(TAG, "onAnimationEnd: onActivityResult 77");
/*为登录状态 则返回false 直接通过判断*/
return false;
}
}
/*登录 登录代理 先是静默登录 然后是显示UI登录*/
private void signIn() {
//get the sign in client and configure for games 创建Client
signInClient = GoogleSignIn.getClient(this, new GoogleSignInOptions
.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build());
Log.d(TAG, "onAnimationEnd: onActivityResult 55,,," + signInClient);
//if silent sign in doesn't work display UI sign in 发起登录
if (!isSignedIn()) {
Log.d(TAG, "onAnimationEnd: onActivityResult 33");
startActivityForResult(signInClient.getSignInIntent(), RC_SIGN_IN);
} else {
//try to sign user in silently
signInSilently();
}
}
private void signInSilently() {
signInClient.silentSignIn().addOnCompleteListener(this,
task -> {
if (task.isSuccessful()) {
signedInAccount = task.getResult();
Log.d(TAG, "signInSilently(): success");
/*以下代码和设置弹窗内账号的状态勾连*/
/*settingsDialog.setPlaySignedIn(true);
updateSettingsIfDisplaying();*/
} else {
/*settingsDialog.setPlaySignedIn(false);
updateSettingsIfDisplaying();*/
Log.d(TAG, "signInSilently(): failure", task.getException());
}
});
}
先判断是否登录,若是没有登录,则开始登录,初始化 GoogleSignInClient,然后链接Google Play。
5)监听登录GooglePlay的结果
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult: 000,,," + data + ",," + resultCode);/*0*/
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
Log.d(TAG, "onActivityResult: 99,,," + result);
if (result.isSuccess()) {
/*点击登录Google Play成功*/
signedInAccount = result.getSignInAccount();
/*settingsDialog.setPlaySignedIn(true);
updateSettingsIfDisplaying();*/
setPopUpView();
Log.d(TAG, "onActivityResult: sign in success");
} else {
/*点击登录Google Play失败*/
Toast.makeText(this, "sign in failed", Toast.LENGTH_LONG).show();
Log.d(TAG, "onActivityResult: sign in failed");
/*settingsDialog.setPlaySignedIn(false);
updateSettingsIfDisplaying();*/
}
}
}
/*onActivityResult登录成功的回调 这里利用登录账号拿到 游戏代理*/
private void setPopUpView() {
gamesClient = Games.getGamesClient(this, signedInAccount);
/*这句话用来设置登录结果及google成就完成时浮窗的父窗口。
若未设置,也可以正常登录及完成成就,但无google自己的浮窗提示。*/
gamesClient.setViewForPopups(findViewById(R.id.gps_popup_welcome));
}
这里的逻辑是登录成功,则拿到游戏代理“gameClient”,然后给它绑定一个布局容器,该容器添加再布局中。
<FrameLayout
android:id="@+id/gps_popup_welcome"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
6)点击按钮显示排行榜和显示成就系统
①显示排行榜
if (!signInIfNotAlready()) {
//if already signed in display leaderboard
// 全局该方法调用两次 首页 这里是用于显示排行榜
Games.getLeaderboardsClient(WelcomeActivity.this,
GoogleSignIn.getLastSignedInAccount(WelcomeActivity.this))
.getLeaderboardIntent(getString(com.lianliankan.game.R.string.leaderboard_high_scores))
.addOnSuccessListener(
intent -> startActivityForResult(intent, RC_LEADERBOARD_UI)
);
}
这里使用到的字符 “leaderboard_high_scores” 即是后台注册的排行榜ID;
②显示成就系统
if (!signInIfNotAlready()) {
//if already signed in display achievements
// 全局该方法调用两次 首页 这里是用于显示成就系统
Games.getAchievementsClient(WelcomeActivity.this,
GoogleSignIn.getLastSignedInAccount(WelcomeActivity.this))
.getAchievementsIntent()
.addOnSuccessListener(
intent -> startActivityForResult(intent, RC_ACHIEVEMENT_UI)
);
}
实例截图如下:
排行榜 截图 成就系统 截图7)完成一局游戏,提交分数
//submit overall score to Google Play leaderboard if signed in
// 全局该方法调用两次 游戏页 这里是用于提交分数至排行榜
if (isSignedIn()) {
Games.getLeaderboardsClient(this, GoogleSignIn.getLastSignedInAccount(this))
.submitScore(getString(R.string.leaderboard_high_scores), questionModel.getScore());
Log.d(TAG, "updateScore: " + questionModel.getScore());
}
8)完成游戏后,解锁某项游戏成就
①拿到成就代理对象
首先也要拿到登录账号GoogleSignInAccount 对象,然后通拿到游戏代理 GamesClient,最后拿到成就代理AchievementsClient。
private GoogleSignInAccount signedInAccount; /*登录账号代理 只使用了一处*/
private GamesClient gamesClient; /*游戏代理 只使用了一处*/
private AchievementsClient achievementsClient; /*成就代理 使用了多处 unlock 即解锁成就 每次使用都要判断是否登录*/
//if signed in on google play setup achievements and leaderboards
signedInAccount = getIntent().getParcelableExtra(MenuActivity.ACCOUNT_PARCEL);
if (signedInAccount != null) {
gamesClient = Games.getGamesClient(this, signedInAccount);
gamesClient.setViewForPopups(findViewById(R.id.gps_popup));
/*成就激活*/
achievementsClient = Games.getAchievementsClient(this, signedInAccount);
}
②解锁成就
//give the player hints
if (isSignedIn()) {
/*完成一项成就——看广告 获取更多的帮助*/
achievementsClient.unlock(getString(R.string.achievement_more_help_please));
}
这里使用到的字符“achievement_more_help_please”,就是在谷歌后台注册不同成就时拿到的不同的成就ID;一项成就对应一个成就ID。
9)退出当前谷歌账号
/*退出 GooglePlay 账号*/
private void signOut() {
signInClient.signOut().addOnCompleteListener(this,
task -> {
StyleableToast.makeText(this, "Signed out", R.style.infoToast).show();
/*设置弹窗 里面登录状态改变*/
settingsDialog.setPlaySignedIn(false);
updateSettingsIfDisplaying();
});
}
最后,推荐一个开源项目帮助理解上述步骤:
https://github.com/OliverStenning/Riddler/commits/master
来源:oschina
链接:https://my.oschina.net/u/4283847/blog/4412944