diff --git a/app/src/main/java/com/mintris/MainActivity.kt b/app/src/main/java/com/mintris/MainActivity.kt index 322f9dd..40818fa 100644 --- a/app/src/main/java/com/mintris/MainActivity.kt +++ b/app/src/main/java/com/mintris/MainActivity.kt @@ -74,14 +74,17 @@ class MainActivity : AppCompatActivity(), // Game state private var isSoundEnabled = true private var isMusicEnabled = true + private var currentScore = 0L + private var currentLevel = 1 + private var piecesPlaced = 0 + private var gameStartTime = 0L private var selectedLevel = 1 private val maxLevel = 20 - private var currentScore = 0 - private var currentLevel = 1 - private var gameStartTime: Long = 0 - private var piecesPlaced: Int = 0 - private var currentTheme = PlayerProgressionManager.THEME_CLASSIC + private var lastLines = 0 // Track the previous lines count + private var lastLinesGroup = 0 // Track which 10-line group we're in (0-9, 10-19, etc.) + private var lastRandomLevel = 0 // Track the level at which we last did a random change private var isRandomModeEnabled = false + private var currentTheme = PlayerProgressionManager.THEME_CLASSIC // Activity result launcher for high score entry private lateinit var highScoreEntryLauncher: ActivityResultLauncher @@ -247,33 +250,7 @@ class MainActivity : AppCompatActivity(), // Set up callbacks gameView.onGameStateChanged = { score, level, lines -> - currentScore = score - currentLevel = level - - binding.scoreText.text = "$score" - binding.currentLevelText.text = "$level" - binding.linesText.text = "$lines" - binding.comboText.text = gameBoard.getCombo().toString() - - // If random mode is enabled and we've leveled up, select random theme and block skin - if (isRandomModeEnabled && level > 1) { - val unlockedThemes = progressionManager.getUnlockedThemes().toList() - val unlockedBlocks = progressionManager.getUnlockedBlocks().toList() - - // Randomly change theme (50% chance) - if (unlockedThemes.isNotEmpty() && Math.random() < 0.5) { - val randomTheme = unlockedThemes.random() - currentTheme = randomTheme - applyTheme(randomTheme) - } - - // Randomly change block skin (50% chance) - if (unlockedBlocks.isNotEmpty() && Math.random() < 0.5) { - val randomBlock = unlockedBlocks.random() - gameView.setBlockSkin(randomBlock) - progressionManager.setSelectedBlockSkin(randomBlock) - } - } + updateGameStateUI(score, level, lines) } gameView.onGameOver = { finalScore -> @@ -608,8 +585,8 @@ class MainActivity : AppCompatActivity(), // Add items in order customizationMenuItems.addAll(listOf( binding.customizationThemeSelector, - binding.randomModeSwitch, binding.customizationBlockSkinSelector, + binding.randomModeSwitch, binding.customizationBackButton ).filterNotNull().filter { it.visibility == View.VISIBLE }) @@ -814,6 +791,9 @@ class MainActivity : AppCompatActivity(), // Set initial game state currentScore = 0 currentLevel = selectedLevel + lastLines = 0 // Reset lastLines to 0 + lastLinesGroup = 0 // Reset lastLinesGroup to 0 + lastRandomLevel = 0 // Reset lastRandomLevel to 0 gameStartTime = System.currentTimeMillis() // Update UI to show initial values @@ -842,33 +822,7 @@ class MainActivity : AppCompatActivity(), // Configure callbacks gameView.onGameStateChanged = { score, level, lines -> - currentScore = score - currentLevel = level - - binding.scoreText.text = "$score" - binding.currentLevelText.text = "$level" - binding.linesText.text = "$lines" - binding.comboText.text = gameBoard.getCombo().toString() - - // If random mode is enabled and we've leveled up, select random theme and block skin - if (isRandomModeEnabled && level > 1) { - val unlockedThemes = progressionManager.getUnlockedThemes().toList() - val unlockedBlocks = progressionManager.getUnlockedBlocks().toList() - - // Randomly change theme (50% chance) - if (unlockedThemes.isNotEmpty() && Math.random() < 0.5) { - val randomTheme = unlockedThemes.random() - currentTheme = randomTheme - applyTheme(randomTheme) - } - - // Randomly change block skin (50% chance) - if (unlockedBlocks.isNotEmpty() && Math.random() < 0.5) { - val randomBlock = unlockedBlocks.random() - gameView.setBlockSkin(randomBlock) - progressionManager.setSelectedBlockSkin(randomBlock) - } - } + updateGameStateUI(score, level, lines) } gameView.onGameOver = { finalScore -> @@ -1897,4 +1851,90 @@ class MainActivity : AppCompatActivity(), } } } + + private fun updateGameStateUI(score: Int, level: Int, lines: Int) { + currentScore = score.toLong() + currentLevel = level + + binding.scoreText.text = "$score" + binding.currentLevelText.text = "$level" + binding.linesText.text = "$lines" + binding.comboText.text = gameBoard.getCombo().toString() + + // If random mode is enabled, check if we should change theme or block skin + if (isRandomModeEnabled) { + // Get the current 10-line group (0 for 0-9, 1 for 10-19, etc.) + val currentLinesGroup = lines / 10 + + // Determine if we should change themes and skins: + // 1. If we've moved to a new 10-line group + // 2. If we've leveled up to a level we haven't applied random to yet + val lineGroupChanged = lines > 0 && currentLinesGroup > lastLinesGroup + val levelIncreased = level > 1 && level > lastRandomLevel + + if (lineGroupChanged || levelIncreased) { + Log.d("RandomMode", "Triggering change - Lines: $lines (group $currentLinesGroup, was $lastLinesGroup), Level: $level (was $lastRandomLevel)") + applyRandomThemeAndBlockSkin() + + // Update tracking variables + lastLinesGroup = currentLinesGroup + lastRandomLevel = level + } + } + + // Update last lines count + lastLines = lines + } + + private fun applyRandomThemeAndBlockSkin() { + val unlockedThemes = progressionManager.getUnlockedThemes().toList() + val unlockedBlocks = progressionManager.getUnlockedBlocks().toList() + + // Log available options + Log.d("RandomMode", "Available themes: ${unlockedThemes.joinToString()}") + Log.d("RandomMode", "Available blocks: ${unlockedBlocks.joinToString()}") + + // Only proceed if there are unlocked themes and blocks + if (unlockedThemes.isNotEmpty() && unlockedBlocks.isNotEmpty()) { + // Apply random theme from unlocked themes - make sure not to pick the current theme + val availableThemes = unlockedThemes.filter { it != currentTheme } + val randomTheme = if (availableThemes.isNotEmpty()) { + availableThemes.random() + } else { + unlockedThemes.random() + } + + // Apply random block skin from unlocked block skins - make sure not to pick the current skin + val currentSkin = gameView.getCurrentBlockSkin() + val availableBlocks = unlockedBlocks.filter { it != currentSkin } + val randomBlock = if (availableBlocks.isNotEmpty()) { + availableBlocks.random() + } else { + unlockedBlocks.random() + } + + Log.d("RandomMode", "Applying random theme: $randomTheme and block skin: $randomBlock") + + // Apply the theme + currentTheme = randomTheme + applyTheme(randomTheme) + + // Force update the block skin with a specific call + gameView.setBlockSkin(randomBlock) + progressionManager.setSelectedBlockSkin(randomBlock) + + // Update the UI to reflect the changes + themeSelector.updateThemes(progressionManager.getUnlockedThemes(), currentTheme) + blockSkinSelector.updateBlockSkins( + progressionManager.getUnlockedBlocks(), + randomBlock, + progressionManager.getPlayerLevel() + ) + + // Add a vibration to indicate the change to the player + gameHaptics.vibrateForPieceLock() + } else { + Log.d("RandomMode", "Cannot apply random theme/skin - no unlocked options available") + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/mintris/game/GameView.kt b/app/src/main/java/com/mintris/game/GameView.kt index 282a701..a89ad77 100644 --- a/app/src/main/java/com/mintris/game/GameView.kt +++ b/app/src/main/java/com/mintris/game/GameView.kt @@ -314,11 +314,29 @@ class GameView @JvmOverloads constructor( * Set the current block skin */ fun setBlockSkin(skinId: String) { - currentBlockSkin = skinId + Log.d("BlockSkin", "Setting block skin from: $currentBlockSkin to: $skinId") + + // Check if the skin exists in our map + if (!blockSkinPaints.containsKey(skinId)) { + Log.e("BlockSkin", "Warning: Unknown block skin: $skinId - available skins: ${blockSkinPaints.keys}") + // Fall back to default skin if the requested one doesn't exist + if (blockSkinPaints.containsKey("block_skin_1")) { + currentBlockSkin = "block_skin_1" + } + } else { + // Set the skin + currentBlockSkin = skinId + } + // Save the selection to SharedPreferences val prefs = context.getSharedPreferences("mintris_progression", Context.MODE_PRIVATE) prefs.edit().putString("selected_block_skin", skinId).commit() + + // Force a refresh of the view invalidate() + + // Log confirmation + Log.d("BlockSkin", "Block skin is now: $currentBlockSkin") } /** diff --git a/app/src/main/java/com/mintris/model/GameBoard.kt b/app/src/main/java/com/mintris/model/GameBoard.kt index 60db089..9dafdea 100644 --- a/app/src/main/java/com/mintris/model/GameBoard.kt +++ b/app/src/main/java/com/mintris/model/GameBoard.kt @@ -39,6 +39,7 @@ class GameBoard( var isHardDropInProgress = false // Make public var isPieceLocking = false // Make public private var isPlayerSoftDrop = false // Track if the drop is player-initiated + private var lastLevel = 1 // Add this to track the previous level // Scoring state private var combo = 0 @@ -660,10 +661,10 @@ class GameBoard( * Update the current level and adjust game parameters */ fun updateLevel(newLevel: Int) { + lastLevel = level level = newLevel.coerceIn(1, 20) startingLevel = level // Store the starting level - // Update game speed based on level (NES formula) - dropInterval = (1000 * Math.pow(0.8, (level - 1).toDouble())).toLong() + dropInterval = getDropIntervalForLevel(level) } /** @@ -690,9 +691,10 @@ class GameBoard( // Reset game state score = 0 level = startingLevel // Use starting level instead of resetting to 1 + lastLevel = level // Reset lastLevel to match the current level lines = 0 isGameOver = false - dropInterval = (1000 * Math.pow(0.8, (level - 1).toDouble())).toLong() // Set speed based on current level + dropInterval = getDropIntervalForLevel(level) // Use helper method // Reset scoring state combo = 0 @@ -730,6 +732,11 @@ class GameBoard( return lastClearedLines.toList() } + /** + * Get the last level + */ + fun getLastLevel(): Int = lastLevel + /** * Update the game state (called by game loop) */ @@ -738,4 +745,17 @@ class GameBoard( moveDown() } } + + /** + * Get the drop interval for the given level + */ + private fun getDropIntervalForLevel(level: Int): Long { + val cappedLevel = level.coerceIn(1, 20) + // Update game speed based on level (NES formula) + return (1000 * Math.pow(0.8, (cappedLevel - 1).toDouble())).toLong() + } + + /** + * Update the game level + */ } \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_main.xml b/app/src/main/res/layout-land/activity_main.xml index bc58860..f4a4d50 100644 --- a/app/src/main/res/layout-land/activity_main.xml +++ b/app/src/main/res/layout-land/activity_main.xml @@ -687,11 +687,18 @@ android:id="@+id/customizationThemeSelector" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="16dp" + android:focusable="true" + android:focusableInTouchMode="true" /> + + + - + - - -