mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-17 23:45:22 +01:00
Enhance: Integrate Google Play Games Services for global leaderboard
- Added global leaderboard functionality via Google Play Games Services. - Implemented sign-in process for Google Play Games and score submission. - Updated UI to include leaderboard buttons in both MainActivity and HighScoresActivity. - Enhanced README to document new online features and leaderboard integration. - Added necessary dependencies in build.gradle and updated AndroidManifest.xml for Google Play Games configuration.
This commit is contained in:
parent
21b2513ad4
commit
220caa39f7
10 changed files with 279 additions and 12 deletions
|
@ -11,6 +11,7 @@ A modern falling block puzzle game for Android, featuring smooth animations, res
|
||||||
- Hard drop and soft drop controls
|
- Hard drop and soft drop controls
|
||||||
- Advanced move detection (e.g., T-Spins) and scoring
|
- Advanced move detection (e.g., T-Spins) and scoring
|
||||||
- Persistent high score system (Top 5)
|
- Persistent high score system (Top 5)
|
||||||
|
- Global leaderboard via Google Play Games Services
|
||||||
|
|
||||||
### Modern Android Features
|
### Modern Android Features
|
||||||
- Optimized for Android 11+ (API 30+)
|
- Optimized for Android 11+ (API 30+)
|
||||||
|
@ -20,6 +21,7 @@ A modern falling block puzzle game for Android, featuring smooth animations, res
|
||||||
- Automatic Dark theme support
|
- Automatic Dark theme support
|
||||||
- Intuitive and responsive touch controls
|
- Intuitive and responsive touch controls
|
||||||
- Full edge-to-edge display utilization
|
- Full edge-to-edge display utilization
|
||||||
|
- Google Play Games Services integration for leaderboards
|
||||||
|
|
||||||
### Scoring System
|
### Scoring System
|
||||||
|
|
||||||
|
@ -74,6 +76,12 @@ Pixelmint Drop features a comprehensive scoring system designed to reward skillf
|
||||||
- Multiple theme options with ability to change manually or enable Random Mode (unlocked when 2+ themes are available).
|
- Multiple theme options with ability to change manually or enable Random Mode (unlocked when 2+ themes are available).
|
||||||
- In Random Mode, themes change automatically every 10 line clears (1 level).
|
- In Random Mode, themes change automatically every 10 line clears (1 level).
|
||||||
|
|
||||||
|
### Online Features
|
||||||
|
- Global leaderboard support through Google Play Games Services
|
||||||
|
- Sign in with your Google account to compete with players worldwide
|
||||||
|
- Your highest scores are automatically submitted to the leaderboard
|
||||||
|
- View the global leaderboard directly from the game
|
||||||
|
|
||||||
## Technical Details
|
## Technical Details
|
||||||
|
|
||||||
### Requirements
|
### Requirements
|
||||||
|
|
|
@ -63,6 +63,8 @@ dependencies {
|
||||||
implementation 'androidx.window:window:1.2.0' // For better display support
|
implementation 'androidx.window:window:1.2.0' // For better display support
|
||||||
implementation 'androidx.window:window-java:1.2.0'
|
implementation 'androidx.window:window-java:1.2.0'
|
||||||
implementation 'com.google.code.gson:gson:2.10.1'
|
implementation 'com.google.code.gson:gson:2.10.1'
|
||||||
|
implementation 'com.google.android.gms:play-services-games-v2:19.0.0'
|
||||||
|
implementation 'com.google.android.gms:play-services-auth:20.7.0'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.pixelmintdrop">
|
android:theme="@style/Theme.pixelmintdrop">
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.android.gms.games.APP_ID"
|
||||||
|
android:value="@string/app_id" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
|
@ -13,6 +13,7 @@ import android.view.KeyEvent
|
||||||
import android.view.InputDevice
|
import android.view.InputDevice
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
|
@ -68,6 +69,11 @@ class HighScoresActivity : AppCompatActivity() {
|
||||||
binding.backButton.setOnClickListener {
|
binding.backButton.setOnClickListener {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up leaderboard button
|
||||||
|
binding.leaderboardButton?.setOnClickListener {
|
||||||
|
showGlobalLeaderboard()
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("HighScoresActivity", "Error in onCreate", e)
|
Log.e("HighScoresActivity", "Error in onCreate", e)
|
||||||
// Show an error message if necessary, or finish gracefully
|
// Show an error message if necessary, or finish gracefully
|
||||||
|
@ -104,8 +110,9 @@ class HighScoresActivity : AppCompatActivity() {
|
||||||
else -> Color.WHITE
|
else -> Color.WHITE
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply theme to back button
|
// Apply theme to buttons
|
||||||
binding.backButton.setTextColor(textColor)
|
binding.backButton.setTextColor(textColor)
|
||||||
|
binding.leaderboardButton?.setTextColor(textColor)
|
||||||
|
|
||||||
// Update adapter theme
|
// Update adapter theme
|
||||||
highScoreAdapter.applyTheme(themeId)
|
highScoreAdapter.applyTheme(themeId)
|
||||||
|
@ -122,6 +129,20 @@ class HighScoresActivity : AppCompatActivity() {
|
||||||
Log.e("HighScoresActivity", "Error updating high scores", e)
|
Log.e("HighScoresActivity", "Error updating high scores", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showGlobalLeaderboard() {
|
||||||
|
try {
|
||||||
|
if (!highScoreManager.isGooglePlaySignedIn()) {
|
||||||
|
Toast.makeText(this, "Signing in to Google Play Games...", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the leaderboard
|
||||||
|
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("HighScoresActivity", "Error showing leaderboard", e)
|
||||||
|
Toast.makeText(this, "Could not open leaderboard", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
@ -143,6 +164,11 @@ class HighScoresActivity : AppCompatActivity() {
|
||||||
finish()
|
finish()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
KeyEvent.KEYCODE_BUTTON_Y -> {
|
||||||
|
// Y button shows global leaderboard
|
||||||
|
showGlobalLeaderboard()
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,10 @@ import androidx.core.view.updatePadding
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
// Google Play Games Services imports
|
||||||
|
import com.google.android.gms.games.PlayGames
|
||||||
|
import com.google.android.gms.games.PlayGamesSdk
|
||||||
|
import com.google.android.gms.games.GamesSignInClient
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(),
|
class MainActivity : AppCompatActivity(),
|
||||||
GamepadController.GamepadConnectionListener,
|
GamepadController.GamepadConnectionListener,
|
||||||
|
@ -68,6 +72,9 @@ class MainActivity : AppCompatActivity(),
|
||||||
// ViewModel
|
// ViewModel
|
||||||
private val viewModel: MainActivityViewModel by viewModels() // Added ViewModel
|
private val viewModel: MainActivityViewModel by viewModels() // Added ViewModel
|
||||||
|
|
||||||
|
// Google Play Games Services
|
||||||
|
private lateinit var gamesSignInClient: GamesSignInClient
|
||||||
|
|
||||||
// UI components
|
// UI components
|
||||||
private lateinit var binding: ActivityMainBinding
|
private lateinit var binding: ActivityMainBinding
|
||||||
private lateinit var gameView: GameView
|
private lateinit var gameView: GameView
|
||||||
|
@ -157,6 +164,13 @@ class MainActivity : AppCompatActivity(),
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
// Initialize Google Play Games Services
|
||||||
|
PlayGamesSdk.initialize(this)
|
||||||
|
gamesSignInClient = PlayGames.getGamesSignInClient(this)
|
||||||
|
|
||||||
|
// Request sign-in silently
|
||||||
|
signInToPlayGames()
|
||||||
|
|
||||||
// Store initial padding values before applying insets
|
// Store initial padding values before applying insets
|
||||||
val initialPausePadding = Rect(binding.pauseContainer.paddingLeft, binding.pauseContainer.paddingTop,
|
val initialPausePadding = Rect(binding.pauseContainer.paddingLeft, binding.pauseContainer.paddingTop,
|
||||||
binding.pauseContainer.paddingRight, binding.pauseContainer.paddingBottom)
|
binding.pauseContainer.paddingRight, binding.pauseContainer.paddingBottom)
|
||||||
|
@ -529,9 +543,16 @@ class MainActivity : AppCompatActivity(),
|
||||||
startGame()
|
startGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// High Scores button
|
||||||
binding.highScoresButton.setOnClickListener {
|
binding.highScoresButton.setOnClickListener {
|
||||||
gameHaptics.performHapticFeedback(it, HapticFeedbackConstants.VIRTUAL_KEY)
|
binding.pauseContainer.visibility = View.GONE
|
||||||
showHighScores()
|
val intent = Intent(this, HighScoresActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Leaderboard button
|
||||||
|
binding.leaderboardButton?.setOnClickListener {
|
||||||
|
showLeaderboard()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.pauseLevelUpButton.setOnClickListener {
|
binding.pauseLevelUpButton.setOnClickListener {
|
||||||
|
@ -815,6 +836,7 @@ class MainActivity : AppCompatActivity(),
|
||||||
binding.pauseRestartButton.setTextColor(themeColor)
|
binding.pauseRestartButton.setTextColor(themeColor)
|
||||||
binding.resumeButton.setTextColor(themeColor)
|
binding.resumeButton.setTextColor(themeColor)
|
||||||
binding.highScoresButton.setTextColor(themeColor)
|
binding.highScoresButton.setTextColor(themeColor)
|
||||||
|
binding.leaderboardButton?.setTextColor(themeColor)
|
||||||
binding.statsButton.setTextColor(themeColor)
|
binding.statsButton.setTextColor(themeColor)
|
||||||
binding.pauseLevelUpButton?.setTextColor(themeColor) // Safe call
|
binding.pauseLevelUpButton?.setTextColor(themeColor) // Safe call
|
||||||
binding.pauseLevelDownButton?.setTextColor(themeColor) // Safe call
|
binding.pauseLevelDownButton?.setTextColor(themeColor) // Safe call
|
||||||
|
@ -1640,6 +1662,7 @@ class MainActivity : AppCompatActivity(),
|
||||||
|
|
||||||
// Group 2: Stats and Scoring
|
// Group 2: Stats and Scoring
|
||||||
orderedViews.add(binding.highScoresButton)
|
orderedViews.add(binding.highScoresButton)
|
||||||
|
orderedViews.add(binding.leaderboardButton)
|
||||||
orderedViews.add(binding.statsButton)
|
orderedViews.add(binding.statsButton)
|
||||||
|
|
||||||
// Group 3: Level selection (use safe calls)
|
// Group 3: Level selection (use safe calls)
|
||||||
|
@ -2206,4 +2229,50 @@ class MainActivity : AppCompatActivity(),
|
||||||
Log.d("RandomMode", "Cannot apply random theme/skin - no unlocked options available")
|
Log.d("RandomMode", "Cannot apply random theme/skin - no unlocked options available")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles sign-in to Google Play Games Services
|
||||||
|
*/
|
||||||
|
private fun signInToPlayGames() {
|
||||||
|
gamesSignInClient.isAuthenticated.addOnCompleteListener { task ->
|
||||||
|
val isAuthenticated = task.isSuccessful && task.result.isAuthenticated
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
// Silent sign-in failed, offer to sign in explicitly
|
||||||
|
Log.d(TAG, "Not authenticated with Play Games, will prompt user later")
|
||||||
|
|
||||||
|
// We don't show UI for this immediately, we'll add a button to the pause menu
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "Already authenticated with Play Games")
|
||||||
|
|
||||||
|
// If we were already authenticated, make sure scores are synced
|
||||||
|
val lastHighScore = highScoreManager.getHighScores().maxByOrNull { it.score }
|
||||||
|
lastHighScore?.let {
|
||||||
|
highScoreManager.getGooglePlayGamesManager().submitScore(it.score.toLong(), this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to show Google Play Games leaderboard
|
||||||
|
private fun showLeaderboard() {
|
||||||
|
gamesSignInClient.isAuthenticated.addOnCompleteListener { task ->
|
||||||
|
val isAuthenticated = task.isSuccessful && task.result.isAuthenticated
|
||||||
|
|
||||||
|
if (isAuthenticated) {
|
||||||
|
// Show leaderboard
|
||||||
|
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this)
|
||||||
|
} else {
|
||||||
|
// Sign in first
|
||||||
|
gamesSignInClient.signIn().addOnCompleteListener { signInTask ->
|
||||||
|
if (signInTask.isSuccessful) {
|
||||||
|
// Now try to show leaderboard again
|
||||||
|
highScoreManager.getGooglePlayGamesManager().showLeaderboard(this)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "Sign-in required to view leaderboard", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package com.pixelmintdrop.model
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignInClient
|
||||||
|
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||||
|
import com.google.android.gms.games.PlayGames
|
||||||
|
import com.google.android.gms.games.PlayGamesSdk
|
||||||
|
import com.google.android.gms.tasks.Task
|
||||||
|
|
||||||
|
class GooglePlayGamesManager(private val context: Context) {
|
||||||
|
private val TAG = "GooglePlayGamesManager"
|
||||||
|
|
||||||
|
// Leaderboard ID
|
||||||
|
companion object {
|
||||||
|
const val LEADERBOARD_ID = "CgkImJW2mKsSEAIQAQ"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the Play Games SDK
|
||||||
|
init {
|
||||||
|
try {
|
||||||
|
PlayGamesSdk.initialize(context)
|
||||||
|
Log.d(TAG, "PlayGamesSdk initialized")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error initializing PlayGamesSdk", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if user is already signed in
|
||||||
|
fun isSignedIn(): Boolean {
|
||||||
|
val account = GoogleSignIn.getLastSignedInAccount(context)
|
||||||
|
return account != null && !account.isExpired
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the sign-in client
|
||||||
|
fun getSignInClient(): GoogleSignInClient {
|
||||||
|
val signInOptions = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN).build()
|
||||||
|
return GoogleSignIn.getClient(context, signInOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle sign-in result
|
||||||
|
fun handleSignInResult(task: Task<GoogleSignInAccount>): Boolean {
|
||||||
|
return if (task.isSuccessful) {
|
||||||
|
Log.d(TAG, "Sign-in successful")
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Sign-in failed", task.exception)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit score to leaderboard (requires an activity for potential sign-in)
|
||||||
|
fun submitScore(score: Long, activity: Activity? = null) {
|
||||||
|
val account = GoogleSignIn.getLastSignedInAccount(context)
|
||||||
|
if (account == null) {
|
||||||
|
Log.w(TAG, "Not signed in, score will not be submitted to Google Play Games")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val leaderboardsClient = PlayGames.getLeaderboardsClient(activity ?: return)
|
||||||
|
leaderboardsClient.submitScore(LEADERBOARD_ID, score)
|
||||||
|
Log.d(TAG, "Score $score submitted to leaderboard $LEADERBOARD_ID")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error submitting score to leaderboard", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the leaderboard
|
||||||
|
fun showLeaderboard(activity: Activity) {
|
||||||
|
val account = GoogleSignIn.getLastSignedInAccount(context)
|
||||||
|
if (account == null) {
|
||||||
|
Log.w(TAG, "Not signed in, cannot show leaderboard")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val leaderboardsClient = PlayGames.getLeaderboardsClient(activity)
|
||||||
|
leaderboardsClient
|
||||||
|
.getLeaderboardIntent(LEADERBOARD_ID)
|
||||||
|
.addOnSuccessListener { intent ->
|
||||||
|
activity.startActivity(intent)
|
||||||
|
}
|
||||||
|
.addOnFailureListener { e ->
|
||||||
|
Log.e(TAG, "Error showing leaderboard", e)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Error showing leaderboard", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,6 +10,7 @@ class HighScoreManager(private val context: Context) {
|
||||||
private val prefs: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
private val prefs: SharedPreferences = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
private val type: Type = object : TypeToken<List<HighScore>>() {}.type
|
private val type: Type = object : TypeToken<List<HighScore>>() {}.type
|
||||||
|
private val googlePlayGamesManager = GooglePlayGamesManager(context)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val PREFS_NAME = "pixelmintdrop_highscores"
|
private const val PREFS_NAME = "pixelmintdrop_highscores"
|
||||||
|
@ -27,6 +28,7 @@ class HighScoreManager(private val context: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addHighScore(highScore: HighScore) {
|
fun addHighScore(highScore: HighScore) {
|
||||||
|
// Save to local high scores
|
||||||
val currentScores = getHighScores().toMutableList()
|
val currentScores = getHighScores().toMutableList()
|
||||||
currentScores.add(highScore)
|
currentScores.add(highScore)
|
||||||
|
|
||||||
|
@ -37,6 +39,9 @@ class HighScoreManager(private val context: Context) {
|
||||||
// Save to SharedPreferences
|
// Save to SharedPreferences
|
||||||
val json = gson.toJson(topScores)
|
val json = gson.toJson(topScores)
|
||||||
prefs.edit().putString(KEY_HIGHSCORES, json).apply()
|
prefs.edit().putString(KEY_HIGHSCORES, json).apply()
|
||||||
|
|
||||||
|
// Submit to Google Play Games leaderboard if signed in
|
||||||
|
submitScoreToGooglePlay(highScore.score)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isHighScore(score: Int): Boolean {
|
fun isHighScore(score: Int): Boolean {
|
||||||
|
@ -44,4 +49,26 @@ class HighScoreManager(private val context: Context) {
|
||||||
return currentScores.size < MAX_HIGHSCORES ||
|
return currentScores.size < MAX_HIGHSCORES ||
|
||||||
score > (currentScores.lastOrNull()?.score ?: 0)
|
score > (currentScores.lastOrNull()?.score ?: 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Submit score to Google Play Games leaderboard
|
||||||
|
private fun submitScoreToGooglePlay(score: Int) {
|
||||||
|
// We don't have an activity here, so we can't submit the score directly
|
||||||
|
// The score will be submitted later when an activity is available
|
||||||
|
try {
|
||||||
|
googlePlayGamesManager.submitScore(score.toLong(), null)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Log error but don't crash
|
||||||
|
android.util.Log.e("HighScoreManager", "Error submitting score to leaderboard", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method to check if user is signed in to Google Play Games
|
||||||
|
fun isGooglePlaySignedIn(): Boolean {
|
||||||
|
return googlePlayGamesManager.isSignedIn()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Google Play Games manager
|
||||||
|
fun getGooglePlayGamesManager(): GooglePlayGamesManager {
|
||||||
|
return googlePlayGamesManager
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -406,6 +406,19 @@
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:fontFamily="sans-serif"
|
android:fontFamily="sans-serif"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/leaderboardButton"
|
||||||
|
android:layout_width="200dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:text="Global Leaderboard"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:fontFamily="sans-serif"
|
||||||
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/statsButton"
|
android:id="@+id/statsButton"
|
||||||
|
|
|
@ -25,15 +25,37 @@
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginBottom="16dp"/>
|
android:layout_marginBottom="16dp"/>
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:id="@+id/backButton"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:orientation="horizontal"
|
||||||
android:background="@color/transparent"
|
android:gravity="center">
|
||||||
android:text="@string/back"
|
|
||||||
android:textColor="@color/white"
|
<Button
|
||||||
android:textSize="18sp"
|
android:id="@+id/backButton"
|
||||||
android:fontFamily="monospace"/>
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:text="@string/back"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:fontFamily="monospace"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/leaderboardButton"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:background="@color/transparent"
|
||||||
|
android:text="Global Leaderboard"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:fontFamily="monospace"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
|
@ -1,6 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">Pixel Mint Drop</string>
|
<string name="app_name">Pixel Mint Drop</string>
|
||||||
|
<string name="app_id">630069234328</string>
|
||||||
<string name="game_over">game over</string>
|
<string name="game_over">game over</string>
|
||||||
<string name="score">score</string>
|
<string name="score">score</string>
|
||||||
<string name="level">level</string>
|
<string name="level">level</string>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue