本文将介绍华为游戏服务,并解说如何在MVVM架构的移动游戏App中应用游戏服务实现账号登录及认证性能。

什么是游戏服务?

游戏服务是华为为挪动开发者提供的用于满足各种移动游戏开发需要的服务。应用游戏服务,您能够轻松地在游戏中实现排行榜、事件、成就、存档等性能。游戏服务无效简化游戏的开发过程,让您能够应用简短有序的代码构造创立游戏我的项目。

华为游戏服务,为您提供以下开发能力,帮忙您更高效地开发游戏:

· 帐号登录

· 游戏防沉迷

· 浮标

· 成就

· 事件

· 排行榜

· 游戏存档

· 玩家数据统计

· 游戏根本信息获取

软件及硬件要求

· Android Studio 3.X 及以上版本

· JDK 1.8 及以上版本

· 您的利用应满足以下条件:

— minSdkVersion: 17

— targetSdkVersion: 29

— compileSdkVersion: 29

开发流程

1. 集成

首先,您要先注册成为华为开发者,并将HMS Core集成到我的项目中。 您能够从上面的链接拜访无关该步骤的资料。

https://medium.com/huawei-dev...

2. 增加依赖

集成HMS Core到我的项目中并在AGC控制台开启游戏服务之后,将所需依赖的库增加到app目录下的build.gradle文件中,如下所示:

dependencies {implementation 'com.huawei.agconnect:agconnect-auth:1.5.1.300'implementation 'com.huawei.hms:base: 5.0.5.300'implementation 'com.huawei.hms:hwid: 5.2.0.300'implementation 'com.huawei.hms:iap:5.0.1.300'implementation 'com.huawei.hms:game: 5.0.4.302'}

3. 创立Application类

当您的利用启动时,游戏服务由Application类触发启动。游戏服务是在这个类中启动的,而此类和我的项目一起启动。创立BaseApplication类后,您须要在Manifest文件中定义它。

class BaseApplication : Application(){    companion object{        lateinit var instance: BaseApplication            private set    }     override fun onCreate() {        super.onCreate()         instance = this         HuaweiMobileServicesUtil.setApplication(this)         HwAds.init(this)    }}

4. 设计登录页面

在所有权限和库都增加到我的项目中后,您能够开始为您的游戏开发登录页面。此时就用到了华为认证服务。认证服务使您能够在管制台上查看游戏的所有用户。此外,认证服务还提供了多种登录形式:蕴含Facebook、Twitter、Google、邮箱、电话号码或华为ID。我将分享一个通用的登录页面设计。以下是一个应用华为ID登录的示例。

您能够在以下链接查看认证服务的文档:

https://developer.huawei.com/...

<androidx.constraintlayout.motion.widget.MotionLayout        xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:app="http://schemas.android.com/apk/res-auto"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        app:layoutDescription="@xml/motion_scene_splash"        android:id="@+id/id_09"        android:layout_height="match_parent">         <ImageView            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:src="@drawable/background"            android:alpha="0.7"            android:id="@+id/id_11"/>        <ImageView            android:id="@+id/imgView_logo"            android:layout_width="130dp"            android:layout_height="130dp"            android:layout_marginTop="80dp"            android:scaleType="centerInside"            android:src="@drawable/vs_logo"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toTopOf="parent" />         <ImageView            android:id="@+id/imgView_logo_rays"            android:layout_width="130dp"            android:layout_height="130dp"            android:layout_marginTop="80dp"            android:scaleType="centerInside"            android:src="@drawable/vs_logo"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toTopOf="parent" />         <ImageView            android:id="@+id/imgView_cloudLeft"            android:layout_width="130dp"            android:layout_height="130dp"            android:layout_marginTop="16dp"            android:scaleType="centerInside"            android:src="@drawable/cloud"            android:translationX="-20dp"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toTopOf="parent"            app:tint="#9E9E9E" />         <ImageView            android:id="@+id/imgView_cloudRight"            android:layout_width="130dp"            android:layout_height="130dp"            android:layout_marginTop="120dp"            android:scaleType="centerInside"            android:src="@drawable/cloud"            android:translationX="20dp"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintTop_toTopOf="parent"            app:tint="#607D8B" />         <LinearLayout            android:id="@+id/linlay_inputs"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:layout_marginStart="30dp"            android:alpha="1"            android:layout_marginLeft="30dp"            android:layout_marginEnd="30dp"            android:layout_marginRight="30dp"            android:gravity="center"            android:layout_marginTop="10dp"            android:orientation="vertical"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toBottomOf="@+id/imgView_cloudRight">             <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:fontFamily="@font/muli_regular"                android:text="Welcome Back"                android:textColor="#000000"                android:textSize="20sp"                android:id="@+id/id_12" />             <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:fontFamily="@font/muli_regular"                android:text="Sign in to continue"                android:textColor="#000000"                android:textSize="14sp"                android:id="@+id/id_13" />             <EditText                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="30dp"                android:background="@drawable/et_background"                android:drawableStart="@drawable/ic_baseline_email_24"                android:drawableLeft="@drawable/ic_baseline_email_24"                android:drawablePadding="16dp"                android:hint="Email"                android:inputType="textEmailAddress"                android:padding="16dp"                android:textSize="14sp"                android:textColor="#000000"                android:fontFamily="@font/muli_regular"                android:id="@+id/id_14"/>             <EditText                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="20dp"                android:background="@drawable/et_background"                android:drawableStart="@drawable/ic_baseline_lock_24"                android:drawableLeft="@drawable/ic_baseline_lock_24"                android:drawableEnd="@drawable/ic_baseline_visibility_24"                android:drawableRight="@drawable/ic_baseline_visibility_24"                android:drawablePadding="16dp"                android:hint="Password"                android:inputType="textPassword"                android:padding="16dp"                android:textSize="14sp"                android:textColor="#000000"                android:fontFamily="@font/muli_regular"                android:id="@+id/id_15"/>             <Button                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="30dp"                android:background="@drawable/button_one"                android:text="@string/signInButton"                android:textAllCaps="false"                android:fontFamily="@font/muli_regular"                android:textColor="#7E675E"                android:id="@+id/id_16"/>         </LinearLayout>         <TextView            android:id="@+id/tv_forgotPassword"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginTop="20dp"            android:layout_marginEnd="30dp"            android:alpha="1"            android:layout_marginRight="30dp"            android:text="Forgot Password?"            android:textColor="#7E675E"            android:textSize="13sp"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintTop_toBottomOf="@id/linlay_inputs" />         <ImageView            android:id="@+id/safads"            android:layout_width="wrap_content"            android:layout_height="100dp"            android:src="@drawable/color_logo"            app:tint="#9E9E9E"            app:layout_constraintBottom_toBottomOf="parent"            app:layout_constraintEnd_toEndOf="parent"            app:layout_constraintStart_toStartOf="parent"            app:layout_constraintTop_toBottomOf="@+id/linlay_inputs"            android:visibility="invisible"/>                </androidx.constraintlayout.motion.widget.MotionLayout>

5. 创立LoginViewModel类

LoginViewModel类将从View类接管、解决数据并将解决过的数据发送到View类。所有的登录操作都将在LoginViewModel类中实现。

首先,在HuaweiIdAuthService对象中创立客户端。

private lateinit var mClient: HuaweiIdAuthService

接下来是开发帐户登记。这样做的目标是完结利用中关上的会话。登记后,咱们须要创立login办法。首先,调用logout办法。而后增加startActivityForResult办法,并将其在View类重写。

LoginViewModel类如下所示:

class LoginViewModel(private val context: Context): ViewModel(){     private lateinit var mClient: HuaweiIdAuthService     fun login(fragment: Fragment){        logout()         val huaweiIdAuthParamsHelper =HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM)        val scopeList: MutableList<Scope> = ArrayList()        scopeList.add(Scope(HwIDConstant.SCOPE.ACCOUNT_BASEPROFILE))        huaweiIdAuthParamsHelper.setScopeList(scopeList)        val authParams = huaweiIdAuthParamsHelper.setAccessToken().createParams()         mClient = HuaweiIdAuthManager.getService(context, authParams)        fragment.startActivityForResult(mClient.signInIntent, 1002)    }     fun logout(){        Log.i(Constants.LOGIN_VIEWMODEL_TAG, "In LogOut Fun.")        val auth = AGConnectAuth.getInstance()        auth.signOut()    }}

6. 创立LoginViewModelFactory类

创立LoginViewModelFactory类,并将上下文设置为参数。此类将返回ViewModel类。

class LoginViewModelFactory(private val context: Context): ViewModelProvider.NewInstanceFactory(){    override fun <T : ViewModel?> create(modelClass: Class<T>): T {        return LoginViewModel(context) as T    }}

7. 创立LoginFragment

在XML文件上增加ViewModel依赖,并将它作为绑定对象。你须要再次关上XML文件,增加变量“viewmodel”,将type增加为ViewModel类目录。

<data>    <variable        name="viewmodel"        type="com.xxx.xxx.viewmodel.LoginViewModel"/></data>

返回LoginFragment并增加工厂类、viewmodel类,并进行绑定。

private lateinit var binding: FragmentLoginBindingprivate lateinit var viewModel: LoginViewModelprivate lateinit var viewModelFactory: LoginViewModelFactory

在onCreateView办法上定义这些对象。

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {         binding = DataBindingUtil.inflate(inflater, R.layout.activity_splash_login, container,false) as ActivitySplashLoginBinding        viewModelFactory =LoginViewModelFactory(requireContext() )        viewModel = ViewModelProviders.of(this, viewModelFactory).get(LoginViewModel::class.java)         return binding.root    }

创立登录按钮点击事件监听,并在ViewModel类中调用login办法。

var gameLoginButton = binding.id16.findViewById<View>(R.id.id_16)gameLoginButton.setOnClickListener {    showProgressDialog()    viewModel.login(this)}

最初,创立onActivityResult办法,查看登录后果。如果登录胜利,您能够看到一些用户信息,比方用户名、ID、国家/地区、年龄等。认证服务提供了丰盛的用户信息,您能够在App中应用认证服务。

override fun onActivityResult(        requestCode: Int,        resultCode: Int,        @Nullable data: Intent?    ) {        super.onActivityResult(requestCode, resultCode, data)        if (requestCode == 1002) {            val signInHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data)            if (signInHuaweiIdTask.isSuccessful) {                val huaweiAccount = signInHuaweiIdTask.result                val accessToken = huaweiAccount.accessToken                Log.w(Constants.LOGIN_FRAGMENT_TAG, "accessToken: $accessToken")                 val credential = HwIdAuthProvider.credentialWithToken(accessToken)                val provider_now = credential.provider                Log.w(Constants.LOGIN_FRAGMENT_TAG, "provider_now: $provider_now")                 AGConnectAuth.getInstance().signIn(credential)                    .addOnSuccessListener { signInResult ->                        val user = AGConnectAuth.getInstance().currentUser                        Log.w(Constants.LOGIN_FRAGMENT_TAG, "Login Success. User Display Name : " + user.displayName)                        userName = user.displayName                       //Start another fragment here.                        (activity as MainActivity?)!!.setSelectedTab(Constants.TAB_LOGIN,Constants.TAB_HOME,false)                         dismisProgressDialog()                     }.addOnFailureListener { e: Exception ->                        Toast.makeText(context, R.string.authenticationError, Toast.LENGTH_SHORT).show()                        Log.w(Constants.LOGIN_FRAGMENT_TAG, "sign in for agc failed: " + e.message)                        dismisProgressDialog()                    }            } else {                Toast.makeText(context, R.string.sıgnInError, Toast.LENGTH_SHORT).show()                Log.e(Constants.LOGIN_FRAGMENT_TAG,"sign in failed : " + (signInHuaweiIdTask.exception as ApiException).statusCode)                 dismisProgressDialog()            }        }    }

论断

当初您能够在游戏App上实现登录性能啦。您也能够跟我一样抉择应用认证服务,因为它能够为您提供多种用户信息,您能够在AGC控制台中查看所有用户。

在下一篇文章中,我将介绍“构建成就”(为游戏玩家自定义配置成就(最高200个),减少玩家的新鲜感和成就感,激励玩家继续参加),并提供一个示例。请关注第二篇文章,以简洁的构造开发您的游戏利用。

参考

游戏服务文档

认证服务文档

欲了解HMS Core更多详情,请参阅:
华为开发者联盟官网
获取开发领导文档
参加开发者探讨请到CSDN社区或者Reddit社区
下载demo和示例代码请到Github或者Gitee
解决集成问题请到Stack Overflow

原文链接:https://developer.huawei.com/...
原作者:胡椒