mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-18 12: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
|
package com.mintris
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
@ -14,6 +15,9 @@ class HighScoreEntryActivity : AppCompatActivity() {
|
||||||
private lateinit var scoreText: TextView
|
private lateinit var scoreText: TextView
|
||||||
private lateinit var saveButton: Button
|
private lateinit var saveButton: Button
|
||||||
|
|
||||||
|
// Track if we already saved to prevent double-saving
|
||||||
|
private var hasSaved = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.high_score_entry)
|
setContentView(R.layout.high_score_entry)
|
||||||
|
@ -28,12 +32,28 @@ class HighScoreEntryActivity : AppCompatActivity() {
|
||||||
scoreText.text = getString(R.string.score) + ": $score"
|
scoreText.text = getString(R.string.score) + ": $score"
|
||||||
|
|
||||||
saveButton.setOnClickListener {
|
saveButton.setOnClickListener {
|
||||||
val name = nameInput.text.toString().trim()
|
// Only allow saving once
|
||||||
if (name.isNotEmpty()) {
|
if (!hasSaved) {
|
||||||
val highScore = HighScore(name, score, level)
|
val name = nameInput.text.toString().trim()
|
||||||
highScoreManager.addHighScore(highScore)
|
if (name.isNotEmpty()) {
|
||||||
finish()
|
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
|
package com.mintris
|
||||||
|
|
||||||
|
import android.animation.ObjectAnimator
|
||||||
|
import android.animation.ValueAnimator
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.VibrationEffect
|
import android.os.VibrationEffect
|
||||||
|
@ -11,6 +14,7 @@ import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import com.mintris.databinding.ActivityMainBinding
|
import com.mintris.databinding.ActivityMainBinding
|
||||||
import com.mintris.game.GameHaptics
|
import com.mintris.game.GameHaptics
|
||||||
import com.mintris.game.GameView
|
import com.mintris.game.GameView
|
||||||
|
@ -20,10 +24,14 @@ import android.view.HapticFeedbackConstants
|
||||||
import com.mintris.model.GameBoard
|
import com.mintris.model.GameBoard
|
||||||
import com.mintris.audio.GameMusic
|
import com.mintris.audio.GameMusic
|
||||||
import com.mintris.model.HighScoreManager
|
import com.mintris.model.HighScoreManager
|
||||||
import android.content.Intent
|
import com.mintris.model.PlayerProgressionManager
|
||||||
import com.mintris.model.StatsManager
|
import com.mintris.model.StatsManager
|
||||||
|
import com.mintris.ui.ProgressionScreen
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import android.graphics.Color
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
@ -36,6 +44,8 @@ class MainActivity : AppCompatActivity() {
|
||||||
private lateinit var titleScreen: TitleScreen
|
private lateinit var titleScreen: TitleScreen
|
||||||
private lateinit var highScoreManager: HighScoreManager
|
private lateinit var highScoreManager: HighScoreManager
|
||||||
private lateinit var statsManager: StatsManager
|
private lateinit var statsManager: StatsManager
|
||||||
|
private lateinit var progressionManager: PlayerProgressionManager
|
||||||
|
private lateinit var progressionScreen: ProgressionScreen
|
||||||
|
|
||||||
// Game state
|
// Game state
|
||||||
private var isSoundEnabled = true
|
private var isSoundEnabled = true
|
||||||
|
@ -46,8 +56,19 @@ class MainActivity : AppCompatActivity() {
|
||||||
private var currentLevel = 1
|
private var currentLevel = 1
|
||||||
private var gameStartTime: Long = 0
|
private var gameStartTime: Long = 0
|
||||||
private var piecesPlaced: Int = 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?) {
|
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)
|
super.onCreate(savedInstanceState)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
|
@ -60,11 +81,30 @@ class MainActivity : AppCompatActivity() {
|
||||||
gameMusic = GameMusic(this)
|
gameMusic = GameMusic(this)
|
||||||
highScoreManager = HighScoreManager(this)
|
highScoreManager = HighScoreManager(this)
|
||||||
statsManager = StatsManager(this)
|
statsManager = StatsManager(this)
|
||||||
|
progressionManager = PlayerProgressionManager(this)
|
||||||
|
|
||||||
|
// Load and apply theme preference
|
||||||
|
currentTheme = loadThemePreference()
|
||||||
|
applyTheme(currentTheme)
|
||||||
|
|
||||||
// Set up game view
|
// Set up game view
|
||||||
gameView.setGameBoard(gameBoard)
|
gameView.setGameBoard(gameBoard)
|
||||||
gameView.setHaptics(gameHaptics)
|
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
|
// Set up title screen
|
||||||
titleScreen.onStartGame = {
|
titleScreen.onStartGame = {
|
||||||
titleScreen.visibility = View.GONE
|
titleScreen.visibility = View.GONE
|
||||||
|
@ -244,6 +284,19 @@ class MainActivity : AppCompatActivity() {
|
||||||
level = currentLevel
|
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
|
// End session and save stats
|
||||||
statsManager.endSession()
|
statsManager.endSession()
|
||||||
|
|
||||||
|
@ -263,16 +316,34 @@ class MainActivity : AppCompatActivity() {
|
||||||
binding.sessionTriplesText.text = getString(R.string.triples, statsManager.getSessionTriples())
|
binding.sessionTriplesText.text = getString(R.string.triples, statsManager.getSessionTriples())
|
||||||
binding.sessionTetrisesText.text = getString(R.string.tetrises, statsManager.getSessionTetrises())
|
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
|
// Check if this is a high score
|
||||||
if (highScoreManager.isHighScore(score)) {
|
if (highScoreManager.isHighScore(score)) {
|
||||||
val intent = Intent(this, HighScoreEntryActivity::class.java).apply {
|
showingHighScore = true
|
||||||
putExtra("score", score)
|
|
||||||
putExtra("level", currentLevel)
|
|
||||||
}
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.gameOverContainer.visibility = View.VISIBLE
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Vibrate to indicate game over
|
// Vibrate to indicate game over
|
||||||
vibrate(VibrationEffect.EFFECT_DOUBLE_CLICK)
|
vibrate(VibrationEffect.EFFECT_DOUBLE_CLICK)
|
||||||
|
@ -283,6 +354,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
*/
|
*/
|
||||||
private fun hideGameOver() {
|
private fun hideGameOver() {
|
||||||
binding.gameOverContainer.visibility = View.GONE
|
binding.gameOverContainer.visibility = View.GONE
|
||||||
|
progressionScreen.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -292,6 +364,9 @@ class MainActivity : AppCompatActivity() {
|
||||||
binding.pauseContainer.visibility = View.VISIBLE
|
binding.pauseContainer.visibility = View.VISIBLE
|
||||||
binding.pauseStartButton.visibility = View.VISIBLE
|
binding.pauseStartButton.visibility = View.VISIBLE
|
||||||
binding.resumeButton.visibility = View.GONE
|
binding.resumeButton.visibility = View.GONE
|
||||||
|
|
||||||
|
// Update theme selector
|
||||||
|
updateThemeSelector()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -346,6 +421,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
gameStartTime = System.currentTimeMillis()
|
gameStartTime = System.currentTimeMillis()
|
||||||
piecesPlaced = 0
|
piecesPlaced = 0
|
||||||
statsManager.startNewSession()
|
statsManager.startNewSession()
|
||||||
|
progressionManager.startNewSession()
|
||||||
gameBoard.updateLevel(selectedLevel)
|
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) {
|
if (titleScreen.visibility == View.GONE && gameView.visibility == View.VISIBLE && binding.gameOverContainer.visibility == View.GONE && binding.pauseContainer.visibility == View.GONE) {
|
||||||
resumeGame()
|
resumeGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update theme selector with available themes when pause screen appears
|
||||||
|
updateThemeSelector()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
|
@ -405,4 +484,79 @@ class MainActivity : AppCompatActivity() {
|
||||||
val intent = Intent(this, HighScoresActivity::class.java)
|
val intent = Intent(this, HighScoresActivity::class.java)
|
||||||
startActivity(intent)
|
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