mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-18 20:55:20 +01:00
Fix high score entry infinite loop issue by using ActivityResultLauncher and proper activity result handling
This commit is contained in:
parent
bae3a01087
commit
3b2f25c61f
2 changed files with 186 additions and 12 deletions
|
@ -1,5 +1,6 @@
|
|||
package com.mintris
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
|
@ -13,6 +14,9 @@ class HighScoreEntryActivity : AppCompatActivity() {
|
|||
private lateinit var nameInput: EditText
|
||||
private lateinit var scoreText: TextView
|
||||
private lateinit var saveButton: Button
|
||||
|
||||
// Track if we already saved to prevent double-saving
|
||||
private var hasSaved = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
@ -28,12 +32,28 @@ class HighScoreEntryActivity : AppCompatActivity() {
|
|||
scoreText.text = getString(R.string.score) + ": $score"
|
||||
|
||||
saveButton.setOnClickListener {
|
||||
val name = nameInput.text.toString().trim()
|
||||
if (name.isNotEmpty()) {
|
||||
val highScore = HighScore(name, score, level)
|
||||
highScoreManager.addHighScore(highScore)
|
||||
finish()
|
||||
// Only allow saving once
|
||||
if (!hasSaved) {
|
||||
val name = nameInput.text.toString().trim()
|
||||
if (name.isNotEmpty()) {
|
||||
hasSaved = true
|
||||
val highScore = HighScore(name, score, level)
|
||||
highScoreManager.addHighScore(highScore)
|
||||
|
||||
// Set result and finish
|
||||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent accidental back button press from causing issues
|
||||
override fun onBackPressed() {
|
||||
// If they haven't saved yet, consider it a cancel
|
||||
if (!hasSaved) {
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
}
|
||||
finish()
|
||||
}
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
package com.mintris
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.VibrationEffect
|
||||
|
@ -11,6 +14,7 @@ import android.widget.Button
|
|||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.mintris.databinding.ActivityMainBinding
|
||||
import com.mintris.game.GameHaptics
|
||||
import com.mintris.game.GameView
|
||||
|
@ -20,10 +24,14 @@ import android.view.HapticFeedbackConstants
|
|||
import com.mintris.model.GameBoard
|
||||
import com.mintris.audio.GameMusic
|
||||
import com.mintris.model.HighScoreManager
|
||||
import android.content.Intent
|
||||
import com.mintris.model.PlayerProgressionManager
|
||||
import com.mintris.model.StatsManager
|
||||
import com.mintris.ui.ProgressionScreen
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import android.graphics.Color
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
|
@ -36,6 +44,8 @@ class MainActivity : AppCompatActivity() {
|
|||
private lateinit var titleScreen: TitleScreen
|
||||
private lateinit var highScoreManager: HighScoreManager
|
||||
private lateinit var statsManager: StatsManager
|
||||
private lateinit var progressionManager: PlayerProgressionManager
|
||||
private lateinit var progressionScreen: ProgressionScreen
|
||||
|
||||
// Game state
|
||||
private var isSoundEnabled = true
|
||||
|
@ -46,8 +56,19 @@ class MainActivity : AppCompatActivity() {
|
|||
private var currentLevel = 1
|
||||
private var gameStartTime: Long = 0
|
||||
private var piecesPlaced: Int = 0
|
||||
private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
|
||||
|
||||
// Activity result launcher for high score entry
|
||||
private lateinit var highScoreEntryLauncher: ActivityResultLauncher<Intent>
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// Register activity result launcher for high score entry
|
||||
highScoreEntryLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
// No matter what the result is, we just show the game over container
|
||||
progressionScreen.visibility = View.GONE
|
||||
binding.gameOverContainer.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
@ -60,11 +81,30 @@ class MainActivity : AppCompatActivity() {
|
|||
gameMusic = GameMusic(this)
|
||||
highScoreManager = HighScoreManager(this)
|
||||
statsManager = StatsManager(this)
|
||||
progressionManager = PlayerProgressionManager(this)
|
||||
|
||||
// Load and apply theme preference
|
||||
currentTheme = loadThemePreference()
|
||||
applyTheme(currentTheme)
|
||||
|
||||
// Set up game view
|
||||
gameView.setGameBoard(gameBoard)
|
||||
gameView.setHaptics(gameHaptics)
|
||||
|
||||
// Set up progression screen
|
||||
progressionScreen = binding.progressionScreen
|
||||
progressionScreen.visibility = View.GONE
|
||||
progressionScreen.onContinue = {
|
||||
progressionScreen.visibility = View.GONE
|
||||
binding.gameOverContainer.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
// Set up theme selector
|
||||
val themeSelector = binding.themeSelector
|
||||
themeSelector.onThemeSelected = { themeId ->
|
||||
applyTheme(themeId)
|
||||
}
|
||||
|
||||
// Set up title screen
|
||||
titleScreen.onStartGame = {
|
||||
titleScreen.visibility = View.GONE
|
||||
|
@ -244,6 +284,19 @@ class MainActivity : AppCompatActivity() {
|
|||
level = currentLevel
|
||||
)
|
||||
|
||||
// Calculate XP earned
|
||||
val xpGained = progressionManager.calculateGameXP(
|
||||
score = score,
|
||||
lines = gameBoard.lines,
|
||||
level = currentLevel,
|
||||
gameTime = gameTime,
|
||||
tetrisCount = statsManager.getSessionTetrises(),
|
||||
perfectClearCount = 0 // Implement perfect clear tracking if needed
|
||||
)
|
||||
|
||||
// Add XP and check for rewards
|
||||
val newRewards = progressionManager.addXP(xpGained)
|
||||
|
||||
// End session and save stats
|
||||
statsManager.endSession()
|
||||
|
||||
|
@ -263,17 +316,35 @@ class MainActivity : AppCompatActivity() {
|
|||
binding.sessionTriplesText.text = getString(R.string.triples, statsManager.getSessionTriples())
|
||||
binding.sessionTetrisesText.text = getString(R.string.tetrises, statsManager.getSessionTetrises())
|
||||
|
||||
// Flag to track if high score screen will be shown
|
||||
var showingHighScore = false
|
||||
|
||||
// Show progression screen first with XP animation
|
||||
binding.gameOverContainer.visibility = View.GONE
|
||||
progressionScreen.visibility = View.VISIBLE
|
||||
progressionScreen.showProgress(progressionManager, xpGained, newRewards)
|
||||
|
||||
// Override the continue button behavior if high score needs to be shown
|
||||
val originalOnContinue = progressionScreen.onContinue
|
||||
|
||||
// Check if this is a high score
|
||||
if (highScoreManager.isHighScore(score)) {
|
||||
val intent = Intent(this, HighScoreEntryActivity::class.java).apply {
|
||||
putExtra("score", score)
|
||||
putExtra("level", currentLevel)
|
||||
showingHighScore = true
|
||||
|
||||
// Set a special onContinue that launches high score entry
|
||||
progressionScreen.onContinue = {
|
||||
val intent = Intent(this, HighScoreEntryActivity::class.java).apply {
|
||||
putExtra("score", score)
|
||||
putExtra("level", currentLevel)
|
||||
}
|
||||
// Use the launcher instead of startActivity
|
||||
highScoreEntryLauncher.launch(intent)
|
||||
|
||||
// Restore original onContinue for next time
|
||||
progressionScreen.onContinue = originalOnContinue
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
binding.gameOverContainer.visibility = View.VISIBLE
|
||||
|
||||
// Vibrate to indicate game over
|
||||
vibrate(VibrationEffect.EFFECT_DOUBLE_CLICK)
|
||||
}
|
||||
|
@ -283,6 +354,7 @@ class MainActivity : AppCompatActivity() {
|
|||
*/
|
||||
private fun hideGameOver() {
|
||||
binding.gameOverContainer.visibility = View.GONE
|
||||
progressionScreen.visibility = View.GONE
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -292,6 +364,9 @@ class MainActivity : AppCompatActivity() {
|
|||
binding.pauseContainer.visibility = View.VISIBLE
|
||||
binding.pauseStartButton.visibility = View.VISIBLE
|
||||
binding.resumeButton.visibility = View.GONE
|
||||
|
||||
// Update theme selector
|
||||
updateThemeSelector()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -346,6 +421,7 @@ class MainActivity : AppCompatActivity() {
|
|||
gameStartTime = System.currentTimeMillis()
|
||||
piecesPlaced = 0
|
||||
statsManager.startNewSession()
|
||||
progressionManager.startNewSession()
|
||||
gameBoard.updateLevel(selectedLevel)
|
||||
}
|
||||
|
||||
|
@ -379,6 +455,9 @@ class MainActivity : AppCompatActivity() {
|
|||
if (titleScreen.visibility == View.GONE && gameView.visibility == View.VISIBLE && binding.gameOverContainer.visibility == View.GONE && binding.pauseContainer.visibility == View.GONE) {
|
||||
resumeGame()
|
||||
}
|
||||
|
||||
// Update theme selector with available themes when pause screen appears
|
||||
updateThemeSelector()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -405,4 +484,79 @@ class MainActivity : AppCompatActivity() {
|
|||
val intent = Intent(this, HighScoresActivity::class.java)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the theme selector with unlocked themes
|
||||
*/
|
||||
private fun updateThemeSelector() {
|
||||
binding.themeSelector.updateThemes(
|
||||
progressionManager.getUnlockedThemes(),
|
||||
currentTheme
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a theme to the game
|
||||
*/
|
||||
private fun applyTheme(themeId: String) {
|
||||
// Only apply if the theme is unlocked
|
||||
if (!progressionManager.isThemeUnlocked(themeId)) return
|
||||
|
||||
// Save the selected theme
|
||||
currentTheme = themeId
|
||||
saveThemePreference(themeId)
|
||||
|
||||
// Apply theme colors based on theme ID
|
||||
when (themeId) {
|
||||
PlayerProgressionManager.THEME_CLASSIC -> {
|
||||
// Default black theme
|
||||
binding.root.setBackgroundColor(Color.BLACK)
|
||||
}
|
||||
PlayerProgressionManager.THEME_NEON -> {
|
||||
// Neon theme with dark purple background
|
||||
binding.root.setBackgroundColor(Color.parseColor("#0D0221"))
|
||||
}
|
||||
PlayerProgressionManager.THEME_MONOCHROME -> {
|
||||
// Monochrome dark gray
|
||||
binding.root.setBackgroundColor(Color.parseColor("#1A1A1A"))
|
||||
}
|
||||
PlayerProgressionManager.THEME_RETRO -> {
|
||||
// Retro arcade theme
|
||||
binding.root.setBackgroundColor(Color.parseColor("#3F2832"))
|
||||
}
|
||||
PlayerProgressionManager.THEME_MINIMALIST -> {
|
||||
// Minimalist white theme
|
||||
binding.root.setBackgroundColor(Color.WHITE)
|
||||
|
||||
// Update text colors for visibility
|
||||
binding.scoreText.setTextColor(Color.BLACK)
|
||||
binding.currentLevelText.setTextColor(Color.BLACK)
|
||||
binding.linesText.setTextColor(Color.BLACK)
|
||||
binding.comboText.setTextColor(Color.BLACK)
|
||||
}
|
||||
PlayerProgressionManager.THEME_GALAXY -> {
|
||||
// Galaxy dark blue theme
|
||||
binding.root.setBackgroundColor(Color.parseColor("#0B0C10"))
|
||||
}
|
||||
}
|
||||
|
||||
// Update the game view to apply theme
|
||||
gameView.invalidate()
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the selected theme in preferences
|
||||
*/
|
||||
private fun saveThemePreference(themeId: String) {
|
||||
val prefs = getSharedPreferences("mintris_settings", Context.MODE_PRIVATE)
|
||||
prefs.edit().putString("selected_theme", themeId).apply()
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the saved theme preference
|
||||
*/
|
||||
private fun loadThemePreference(): String {
|
||||
val prefs = getSharedPreferences("mintris_settings", Context.MODE_PRIVATE)
|
||||
return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue