diff --git a/app/src/main/java/com/mintris/HighScoreEntryActivity.kt b/app/src/main/java/com/mintris/HighScoreEntryActivity.kt index 313685b..8829d52 100644 --- a/app/src/main/java/com/mintris/HighScoreEntryActivity.kt +++ b/app/src/main/java/com/mintris/HighScoreEntryActivity.kt @@ -5,39 +5,46 @@ import android.os.Bundle import android.widget.Button import android.widget.EditText import android.widget.TextView +import android.view.View import androidx.appcompat.app.AppCompatActivity +import com.mintris.databinding.HighScoreEntryBinding import com.mintris.model.HighScore import com.mintris.model.HighScoreManager +import com.mintris.model.PlayerProgressionManager +import android.graphics.Color class HighScoreEntryActivity : AppCompatActivity() { + private lateinit var binding: HighScoreEntryBinding private lateinit var highScoreManager: HighScoreManager - private lateinit var nameInput: EditText - private lateinit var scoreText: TextView - private lateinit var saveButton: Button + private lateinit var progressionManager: PlayerProgressionManager + private var currentTheme = PlayerProgressionManager.THEME_CLASSIC + private var score: Int = 0 // Track if we already saved to prevent double-saving private var hasSaved = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.high_score_entry) + binding = HighScoreEntryBinding.inflate(layoutInflater) + setContentView(binding.root) highScoreManager = HighScoreManager(this) - nameInput = findViewById(R.id.nameInput) - scoreText = findViewById(R.id.scoreText) - saveButton = findViewById(R.id.saveButton) + progressionManager = PlayerProgressionManager(this) + + // Load and apply theme + currentTheme = loadThemePreference() + applyTheme(currentTheme) - val score = intent.getIntExtra("score", 0) - val level = intent.getIntExtra("level", 1) - scoreText.text = getString(R.string.score) + ": $score" + score = intent.getIntExtra("score", 0) + binding.scoreText.text = "Score: $score" - saveButton.setOnClickListener { + binding.saveButton.setOnClickListener { // Only allow saving once if (!hasSaved) { - val name = nameInput.text.toString().trim() + val name = binding.nameInput.text.toString().trim() if (name.isNotEmpty()) { hasSaved = true - val highScore = HighScore(name, score, level) + val highScore = HighScore(name, score, 1) highScoreManager.addHighScore(highScore) // Set result and finish @@ -50,10 +57,49 @@ class HighScoreEntryActivity : AppCompatActivity() { // Prevent accidental back button press from causing issues override fun onBackPressed() { + super.onBackPressed() // If they haven't saved yet, consider it a cancel if (!hasSaved) { setResult(Activity.RESULT_CANCELED) } finish() } + + private fun loadThemePreference(): String { + val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) + return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC + } + + private fun applyTheme(themeId: String) { + // Set background color + val backgroundColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") + PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832") + PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10") + else -> Color.BLACK + } + binding.root.setBackgroundColor(backgroundColor) + + // Set text color + val textColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF") + PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F") + PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1") + else -> Color.WHITE + } + + // Apply text color to score and input + binding.scoreText.setTextColor(textColor) + binding.nameInput.setTextColor(textColor) + binding.nameInput.setHintTextColor(Color.argb(128, Color.red(textColor), Color.green(textColor), Color.blue(textColor))) + + // Apply theme to submit button + binding.saveButton.setTextColor(textColor) + } } \ No newline at end of file diff --git a/app/src/main/java/com/mintris/HighScoresActivity.kt b/app/src/main/java/com/mintris/HighScoresActivity.kt index da6dd9c..ae525bf 100644 --- a/app/src/main/java/com/mintris/HighScoresActivity.kt +++ b/app/src/main/java/com/mintris/HighScoresActivity.kt @@ -2,44 +2,116 @@ package com.mintris import android.os.Bundle import android.widget.Button +import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.mintris.databinding.HighScoresBinding import com.mintris.model.HighScoreAdapter import com.mintris.model.HighScoreManager +import com.mintris.model.PlayerProgressionManager +import android.graphics.Color +import android.util.Log class HighScoresActivity : AppCompatActivity() { + private lateinit var binding: HighScoresBinding private lateinit var highScoreManager: HighScoreManager private lateinit var highScoreAdapter: HighScoreAdapter - private lateinit var highScoresList: RecyclerView - private lateinit var backButton: Button + private lateinit var progressionManager: PlayerProgressionManager + private var currentTheme = PlayerProgressionManager.THEME_CLASSIC override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.high_scores) - - highScoreManager = HighScoreManager(this) - highScoresList = findViewById(R.id.highScoresList) - backButton = findViewById(R.id.backButton) - - highScoreAdapter = HighScoreAdapter() - highScoresList.layoutManager = LinearLayoutManager(this) - highScoresList.adapter = highScoreAdapter - - updateHighScores() - - backButton.setOnClickListener { + + try { + binding = HighScoresBinding.inflate(layoutInflater) + setContentView(binding.root) + + highScoreManager = HighScoreManager(this) + progressionManager = PlayerProgressionManager(this) + + // Load and apply theme + currentTheme = loadThemePreference() + + // Initialize adapter before applying theme + highScoreAdapter = HighScoreAdapter() + + // Set up RecyclerView + binding.highScoresList.layoutManager = LinearLayoutManager(this) + binding.highScoresList.adapter = highScoreAdapter + + // Now apply theme to UI + applyTheme(currentTheme) + + // Load high scores + updateHighScores() + + // Set up back button + binding.backButton.setOnClickListener { + finish() + } + } catch (e: Exception) { + Log.e("HighScoresActivity", "Error in onCreate", e) + // Show an error message if necessary, or finish gracefully finish() } } + private fun loadThemePreference(): String { + val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) + return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC + } + + private fun applyTheme(themeId: String) { + try { + // Set background color + val backgroundColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") + PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832") + PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10") + else -> Color.BLACK + } + binding.root.setBackgroundColor(backgroundColor) + + // Set text color + val textColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF") + PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F") + PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1") + else -> Color.WHITE + } + + // Apply theme to back button + binding.backButton.setTextColor(textColor) + + // Update adapter theme + highScoreAdapter.applyTheme(themeId) + } catch (e: Exception) { + Log.e("HighScoresActivity", "Error applying theme: $themeId", e) + } + } + private fun updateHighScores() { - val scores = highScoreManager.getHighScores() - highScoreAdapter.updateHighScores(scores) + try { + val scores = highScoreManager.getHighScores() + highScoreAdapter.updateHighScores(scores) + } catch (e: Exception) { + Log.e("HighScoresActivity", "Error updating high scores", e) + } } override fun onResume() { super.onResume() - updateHighScores() + try { + updateHighScores() + } catch (e: Exception) { + Log.e("HighScoresActivity", "Error in onResume", e) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/mintris/MainActivity.kt b/app/src/main/java/com/mintris/MainActivity.kt index 83fdd6c..e403d6c 100644 --- a/app/src/main/java/com/mintris/MainActivity.kt +++ b/app/src/main/java/com/mintris/MainActivity.kt @@ -102,7 +102,16 @@ class MainActivity : AppCompatActivity() { // Set up theme selector val themeSelector = binding.themeSelector themeSelector.onThemeSelected = { themeId -> + // Apply the new theme applyTheme(themeId) + + // Provide haptic feedback as a cue that the theme changed + gameHaptics.vibrateForPieceLock() + + // Refresh the pause menu to immediately show theme changes + if (binding.pauseContainer.visibility == View.VISIBLE) { + showPauseMenu() + } } // Set up title screen @@ -381,6 +390,38 @@ class MainActivity : AppCompatActivity() { binding.pauseLevelBadge.setLevel(progressionManager.getPlayerLevel()) binding.pauseLevelBadge.setThemeColor(getThemeColor(currentTheme)) + // Get theme color + val textColor = getThemeColor(currentTheme) + + // Apply theme color to pause container background + val backgroundColor = when (currentTheme) { + PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") + PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832") + PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10") + else -> Color.BLACK + } + binding.pauseContainer.setBackgroundColor(backgroundColor) + + // Apply theme colors to buttons + binding.pauseStartButton.setTextColor(textColor) + binding.pauseRestartButton.setTextColor(textColor) + binding.resumeButton.setTextColor(textColor) + binding.highScoresButton.setTextColor(textColor) + binding.statsButton.setTextColor(textColor) + binding.pauseLevelText.setTextColor(textColor) + binding.pauseLevelUpButton.setTextColor(textColor) + binding.pauseLevelDownButton.setTextColor(textColor) + binding.settingsButton.setTextColor(textColor) + binding.musicToggle.setColorFilter(textColor) + + // Apply theme colors to text elements + binding.settingsTitle.setTextColor(textColor) + binding.selectLevelText.setTextColor(textColor) + binding.musicText.setTextColor(textColor) + // Update theme selector updateThemeSelector() } @@ -567,6 +608,10 @@ class MainActivity : AppCompatActivity() { progressionScreen.applyTheme(themeId) } + // Apply theme color to the stats button + val textColor = getThemeColor(currentTheme) + binding.statsButton.setTextColor(textColor) + // Update the game view to apply theme gameView.invalidate() } diff --git a/app/src/main/java/com/mintris/StatsActivity.kt b/app/src/main/java/com/mintris/StatsActivity.kt index edcc765..e7f6f3e 100644 --- a/app/src/main/java/com/mintris/StatsActivity.kt +++ b/app/src/main/java/com/mintris/StatsActivity.kt @@ -7,12 +7,16 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import com.mintris.databinding.ActivityStatsBinding import com.mintris.model.StatsManager +import com.mintris.model.PlayerProgressionManager +import android.graphics.Color import java.text.SimpleDateFormat import java.util.* class StatsActivity : AppCompatActivity() { private lateinit var binding: ActivityStatsBinding private lateinit var statsManager: StatsManager + private lateinit var progressionManager: PlayerProgressionManager + private var currentTheme = PlayerProgressionManager.THEME_CLASSIC override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -20,6 +24,11 @@ class StatsActivity : AppCompatActivity() { setContentView(binding.root) statsManager = StatsManager(this) + progressionManager = PlayerProgressionManager(this) + + // Load and apply theme + currentTheme = loadThemePreference() + applyTheme(currentTheme) // Set up back button binding.backButton.setOnClickListener { @@ -34,6 +43,54 @@ class StatsActivity : AppCompatActivity() { updateStats() } + private fun loadThemePreference(): String { + val prefs = getSharedPreferences("mintris_settings", MODE_PRIVATE) + return prefs.getString("selected_theme", PlayerProgressionManager.THEME_CLASSIC) ?: PlayerProgressionManager.THEME_CLASSIC + } + + private fun applyTheme(themeId: String) { + // Set background color + val backgroundColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.BLACK + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#0D0221") + PlayerProgressionManager.THEME_MONOCHROME -> Color.parseColor("#1A1A1A") + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#3F2832") + PlayerProgressionManager.THEME_MINIMALIST -> Color.WHITE + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#0B0C10") + else -> Color.BLACK + } + binding.root.setBackgroundColor(backgroundColor) + + // Set text color + val textColor = when (themeId) { + PlayerProgressionManager.THEME_CLASSIC -> Color.WHITE + PlayerProgressionManager.THEME_NEON -> Color.parseColor("#FF00FF") + PlayerProgressionManager.THEME_MONOCHROME -> Color.LTGRAY + PlayerProgressionManager.THEME_RETRO -> Color.parseColor("#FF5A5F") + PlayerProgressionManager.THEME_MINIMALIST -> Color.BLACK + PlayerProgressionManager.THEME_GALAXY -> Color.parseColor("#66FCF1") + else -> Color.WHITE + } + + // Apply text color to all TextViews + binding.totalGamesText.setTextColor(textColor) + binding.totalScoreText.setTextColor(textColor) + binding.totalLinesText.setTextColor(textColor) + binding.totalPiecesText.setTextColor(textColor) + binding.totalTimeText.setTextColor(textColor) + binding.totalSinglesText.setTextColor(textColor) + binding.totalDoublesText.setTextColor(textColor) + binding.totalTriplesText.setTextColor(textColor) + binding.totalTetrisesText.setTextColor(textColor) + binding.maxLevelText.setTextColor(textColor) + binding.maxScoreText.setTextColor(textColor) + binding.maxLinesText.setTextColor(textColor) + + // Apply theme to buttons + binding.backButton.setTextColor(textColor) + binding.resetStatsButton.setTextColor(textColor) + } + private fun showResetConfirmationDialog() { AlertDialog.Builder(this) .setTitle("Reset Stats") diff --git a/app/src/main/java/com/mintris/model/HighScoreAdapter.kt b/app/src/main/java/com/mintris/model/HighScoreAdapter.kt index 1f86531..de4ec52 100644 --- a/app/src/main/java/com/mintris/model/HighScoreAdapter.kt +++ b/app/src/main/java/com/mintris/model/HighScoreAdapter.kt @@ -1,5 +1,6 @@ package com.mintris.model +import android.graphics.Color import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -9,6 +10,8 @@ import com.mintris.R class HighScoreAdapter : RecyclerView.Adapter() { private var highScores: List = emptyList() + private var currentTheme = "theme_classic" // Default theme + private var textColor = Color.WHITE // Default text color fun updateHighScores(newHighScores: List) { highScores = newHighScores @@ -24,14 +27,19 @@ class HighScoreAdapter : RecyclerView.Adapter Color.WHITE + "theme_neon" -> Color.parseColor("#FF00FF") + "theme_monochrome" -> Color.LTGRAY + "theme_retro" -> Color.parseColor("#FF5A5F") + "theme_minimalist" -> Color.BLACK + "theme_galaxy" -> Color.parseColor("#66FCF1") + else -> Color.WHITE + } + + notifyDataSetChanged() + } } \ No newline at end of file diff --git a/app/src/main/java/com/mintris/model/PlayerProgressionManager.kt b/app/src/main/java/com/mintris/model/PlayerProgressionManager.kt index d25e9fd..e9260bd 100644 --- a/app/src/main/java/com/mintris/model/PlayerProgressionManager.kt +++ b/app/src/main/java/com/mintris/model/PlayerProgressionManager.kt @@ -286,15 +286,15 @@ class PlayerProgressionManager(context: Context) { private const val KEY_UNLOCKED_BADGES = "unlocked_badges" // XP curve parameters - private const val BASE_XP = 5000.0 // Base XP for level 1 (increased from 2500) - private const val XP_CURVE_FACTOR = 2.2 // Exponential factor for XP curve (increased from 2.0) + private const val BASE_XP = 4000.0 // Base XP for level 1 (reduced from 5000) + private const val XP_CURVE_FACTOR = 1.9 // Exponential factor for XP curve (reduced from 2.2) // XP calculation constants - private const val LEVEL_MULTIPLIER = 0.1 // 10% bonus per level - private const val XP_PER_LINE = 10L - private const val TETRIS_XP_BONUS = 50L - private const val PERFECT_CLEAR_XP_BONUS = 200L - private const val TIME_XP_PER_MINUTE = 5L + private const val LEVEL_MULTIPLIER = 0.15 // 15% bonus per level (increased from 10%) + private const val XP_PER_LINE = 15L // Increased from 10 + private const val TETRIS_XP_BONUS = 75L // Increased from 50 + private const val PERFECT_CLEAR_XP_BONUS = 250L // Increased from 200 + private const val TIME_XP_PER_MINUTE = 8L // Increased from 5 // Theme IDs with required levels const val THEME_CLASSIC = "theme_classic" diff --git a/app/src/main/java/com/mintris/ui/ThemeSelector.kt b/app/src/main/java/com/mintris/ui/ThemeSelector.kt index 3be59c7..1653ab2 100644 --- a/app/src/main/java/com/mintris/ui/ThemeSelector.kt +++ b/app/src/main/java/com/mintris/ui/ThemeSelector.kt @@ -86,16 +86,18 @@ class ThemeSelector @JvmOverloads constructor( // Set card background color based on theme setCardBackgroundColor(themeInfo.primaryColor) - // Add stroke for selected theme + // Add more noticeable visual indicator for selected theme if (isSelected) { setContentPadding(4, 4, 4, 4) // Create a gradient drawable for the border val gradientDrawable = android.graphics.drawable.GradientDrawable().apply { setColor(themeInfo.primaryColor) - setStroke(4, Color.WHITE) + setStroke(6, Color.WHITE) // Thicker border cornerRadius = 12f } background = gradientDrawable + // Add glow effect via elevation + cardElevation = 12f } // Set card dimensions @@ -194,9 +196,29 @@ class ThemeSelector @JvmOverloads constructor( card.setOnClickListener { // Only trigger callback if this isn't already the selected theme if (themeId != selectedTheme) { - // Update visual state - themeCards[selectedTheme]?.cardElevation = 2f - card.cardElevation = 8f + // Update previously selected card + themeCards[selectedTheme]?.let { prevCard -> + prevCard.cardElevation = 2f + // Reset any special styling + prevCard.background = null + prevCard.setCardBackgroundColor(getThemes()[selectedTheme]?.primaryColor ?: Color.BLACK) + } + + // Update visual state of newly selected card + card.cardElevation = 12f + + // Flash animation for selection feedback + val flashColor = Color.WHITE + val originalColor = themeInfo.primaryColor + + // Create animator for flash effect + val flashAnimator = android.animation.ValueAnimator.ofArgb(flashColor, originalColor) + flashAnimator.duration = 300 // 300ms + flashAnimator.addUpdateListener { animator -> + val color = animator.animatedValue as Int + card.setCardBackgroundColor(color) + } + flashAnimator.start() // Update selected theme selectedTheme = themeId diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index e978405..371cb8c 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -263,6 +263,7 @@ android:layout_marginBottom="32dp">