mirror of
https://github.com/cmclark00/mintris.git
synced 2025-05-18 02:55:19 +01:00
Add random mode toggle and fix resource linking issues
This commit is contained in:
parent
0b78bf7833
commit
b2a9c40539
6 changed files with 209 additions and 100 deletions
|
@ -45,6 +45,7 @@ import android.widget.ScrollView
|
|||
import android.widget.ImageButton
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.widget.TextView
|
||||
import android.widget.Switch
|
||||
|
||||
class MainActivity : AppCompatActivity(),
|
||||
GamepadController.GamepadConnectionListener,
|
||||
|
@ -80,6 +81,7 @@ class MainActivity : AppCompatActivity(),
|
|||
private var gameStartTime: Long = 0
|
||||
private var piecesPlaced: Int = 0
|
||||
private var currentTheme = PlayerProgressionManager.THEME_CLASSIC
|
||||
private var isRandomModeEnabled = false
|
||||
|
||||
// Activity result launcher for high score entry
|
||||
private lateinit var highScoreEntryLauncher: ActivityResultLauncher<Intent>
|
||||
|
@ -138,6 +140,10 @@ class MainActivity : AppCompatActivity(),
|
|||
blockSkinSelector = binding.customizationBlockSkinSelector!!
|
||||
pauseMenuScrollView = binding.pauseMenuScrollView
|
||||
|
||||
// Load random mode setting
|
||||
isRandomModeEnabled = getSharedPreferences("com.mintris.preferences", Context.MODE_PRIVATE)
|
||||
.getBoolean("random_mode_enabled", false)
|
||||
|
||||
// Initialize gamepad controller
|
||||
gamepadController = GamepadController(gameView)
|
||||
gamepadController.setGamepadConnectionListener(this)
|
||||
|
@ -241,16 +247,33 @@ class MainActivity : AppCompatActivity(),
|
|||
|
||||
// Set up callbacks
|
||||
gameView.onGameStateChanged = { score, level, lines ->
|
||||
updateUI(score, level, lines)
|
||||
}
|
||||
currentScore = score
|
||||
currentLevel = level
|
||||
|
||||
// Track pieces placed using callback
|
||||
gameBoard.onPieceLock = {
|
||||
// Increment pieces placed counter
|
||||
piecesPlaced++
|
||||
binding.scoreText.text = "$score"
|
||||
binding.currentLevelText.text = "$level"
|
||||
binding.linesText.text = "$lines"
|
||||
binding.comboText.text = gameBoard.getCombo().toString()
|
||||
|
||||
// Provide haptic feedback
|
||||
gameHaptics.vibrateForPieceLock()
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gameView.onGameOver = { finalScore ->
|
||||
|
@ -525,8 +548,8 @@ class MainActivity : AppCompatActivity(),
|
|||
* Show customization menu
|
||||
*/
|
||||
private fun showCustomizationMenu() {
|
||||
binding.customizationContainer.visibility = View.VISIBLE
|
||||
binding.pauseContainer.visibility = View.GONE
|
||||
binding.customizationContainer.visibility = View.VISIBLE
|
||||
|
||||
// Get theme colors
|
||||
val themeColor = getThemeColor(currentTheme)
|
||||
|
@ -535,58 +558,48 @@ class MainActivity : AppCompatActivity(),
|
|||
// Apply background color to customization container
|
||||
binding.customizationContainer.setBackgroundColor(backgroundColor)
|
||||
|
||||
// Update level badge
|
||||
// Update level badge with player's level and theme color
|
||||
binding.customizationLevelBadge.setLevel(progressionManager.getPlayerLevel())
|
||||
binding.customizationLevelBadge.setThemeColor(themeColor)
|
||||
|
||||
// Apply theme colors to text and buttons
|
||||
binding.customizationTitle.setTextColor(themeColor)
|
||||
binding.customizationBackButton.setTextColor(themeColor)
|
||||
|
||||
// Apply theme colors to all text views in the container
|
||||
// Apply theme color to all text views in the container
|
||||
applyThemeColorToTextViews(binding.customizationContainer, themeColor)
|
||||
|
||||
// Update theme and block skin selectors
|
||||
binding.customizationThemeSelector.updateThemes(
|
||||
progressionManager.getUnlockedThemes(),
|
||||
currentTheme
|
||||
// Update theme selector with available themes
|
||||
binding.customizationThemeSelector?.updateThemes(
|
||||
unlockedThemes = progressionManager.getUnlockedThemes(),
|
||||
currentTheme = currentTheme
|
||||
)
|
||||
|
||||
// Set up block skin selector callback
|
||||
binding.customizationBlockSkinSelector.onBlockSkinSelected = { selectedSkin ->
|
||||
// Update the game view with the selected block skin
|
||||
gameView.setBlockSkin(selectedSkin)
|
||||
// Save the selection
|
||||
progressionManager.setSelectedBlockSkin(selectedSkin)
|
||||
}
|
||||
|
||||
// Update block skin selector with current selection
|
||||
binding.customizationBlockSkinSelector.updateBlockSkins(
|
||||
// Update block skin selector with available skins
|
||||
binding.customizationBlockSkinSelector?.updateBlockSkins(
|
||||
progressionManager.getUnlockedBlocks(),
|
||||
gameView.getCurrentBlockSkin(),
|
||||
progressionManager.getPlayerLevel()
|
||||
)
|
||||
|
||||
// Reset scroll position
|
||||
binding.customizationMenuScrollView.scrollTo(0, 0)
|
||||
// Set up block skin selection callback
|
||||
binding.customizationBlockSkinSelector?.onBlockSkinSelected = { blockSkin ->
|
||||
gameView.setBlockSkin(blockSkin)
|
||||
progressionManager.setSelectedBlockSkin(blockSkin)
|
||||
gameHaptics.vibrateForPieceLock()
|
||||
}
|
||||
|
||||
// Initialize customization menu items
|
||||
customizationMenuItems.clear()
|
||||
customizationMenuItems.addAll(listOf(
|
||||
binding.customizationThemeSelector,
|
||||
binding.customizationBlockSkinSelector,
|
||||
binding.customizationBackButton
|
||||
).filterNotNull().filter { it.visibility == View.VISIBLE })
|
||||
|
||||
// Set initial selection and highlight
|
||||
currentCustomizationMenuSelection = 0
|
||||
highlightCustomizationMenuItem(currentCustomizationMenuSelection)
|
||||
|
||||
// Set initial focus to theme selector
|
||||
binding.customizationThemeSelector.requestFocus()
|
||||
|
||||
// Initialize customization menu navigation
|
||||
// Initialize customization menu items for gamepad navigation
|
||||
initCustomizationMenuNavigation()
|
||||
|
||||
// Set up random mode switch
|
||||
binding.randomModeSwitch?.apply {
|
||||
isChecked = isRandomModeEnabled
|
||||
isEnabled = progressionManager.getPlayerLevel() >= 5
|
||||
setOnCheckedChangeListener { _, isChecked ->
|
||||
isRandomModeEnabled = isChecked
|
||||
getSharedPreferences("com.mintris.preferences", Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
.putBoolean("random_mode_enabled", isChecked)
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initCustomizationMenuNavigation() {
|
||||
|
@ -595,6 +608,7 @@ class MainActivity : AppCompatActivity(),
|
|||
// Add items in order
|
||||
customizationMenuItems.addAll(listOf(
|
||||
binding.customizationThemeSelector,
|
||||
binding.randomModeSwitch,
|
||||
binding.customizationBlockSkinSelector,
|
||||
binding.customizationBackButton
|
||||
).filterNotNull().filter { it.visibility == View.VISIBLE })
|
||||
|
@ -835,6 +849,26 @@ class MainActivity : AppCompatActivity(),
|
|||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gameView.onGameOver = { finalScore ->
|
||||
|
@ -1431,7 +1465,7 @@ class MainActivity : AppCompatActivity(),
|
|||
item.scaleX = 1.0f
|
||||
item.scaleY = 1.0f
|
||||
}
|
||||
// Reset background/focus state for all items before applying highlight
|
||||
// Reset
|
||||
when (item) {
|
||||
is Button -> item.background = ColorDrawable(Color.TRANSPARENT)
|
||||
is ImageButton -> item.background = null // Let default background handle non-selected
|
||||
|
@ -1470,37 +1504,34 @@ class MainActivity : AppCompatActivity(),
|
|||
item.background = it
|
||||
}
|
||||
} ?: run {
|
||||
// Absolute fallback: create a border if drawable fails
|
||||
item.background = GradientDrawable().apply {
|
||||
// Fallback to simple border if drawable not found
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
}
|
||||
}
|
||||
is ImageButton -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT) // Keep original button look, just add border
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
// Similar handling for ImageButton
|
||||
ContextCompat.getDrawable(this, R.drawable.menu_item_selected)?.mutate()?.let {
|
||||
if (it is GradientDrawable) {
|
||||
it.setStroke(borderWidth, highlightBorderColor)
|
||||
item.background = it
|
||||
} else {
|
||||
it.setTint(highlightBorderColor)
|
||||
item.background = it
|
||||
}
|
||||
} ?: run {
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
}
|
||||
}
|
||||
is ThemeSelector -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.setHasFocus(true) // Tell selector it HAS component focus
|
||||
}
|
||||
is BlockSkinSelector -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.setHasFocus(true) // Tell selector it HAS component focus
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1726,6 +1757,8 @@ class MainActivity : AppCompatActivity(),
|
|||
|
||||
val themeColor = getThemeColor(currentTheme)
|
||||
val highlightBorderColor = themeColor
|
||||
val borderWidth = 4 // Define border width for highlight
|
||||
val cornerRadius = 12f
|
||||
|
||||
customizationMenuItems.forEachIndexed { i, item ->
|
||||
val isSelected = (i == index)
|
||||
|
@ -1747,58 +1780,55 @@ class MainActivity : AppCompatActivity(),
|
|||
item.background = ColorDrawable(Color.TRANSPARENT)
|
||||
item.setHasFocus(false)
|
||||
}
|
||||
is Switch -> {
|
||||
item.background = ColorDrawable(Color.TRANSPARENT)
|
||||
}
|
||||
}
|
||||
|
||||
if (isSelected) {
|
||||
if (item is Button || item is ImageButton) {
|
||||
item.scaleX = 1.1f
|
||||
item.scaleY = 1.1f
|
||||
}
|
||||
|
||||
val borderWidth = 4
|
||||
val cornerRadius = 12f
|
||||
|
||||
when (item) {
|
||||
is Button -> {
|
||||
ContextCompat.getDrawable(this, R.drawable.menu_item_selected)?.mutate()?.let {
|
||||
if (it is GradientDrawable) {
|
||||
it.setStroke(borderWidth, highlightBorderColor)
|
||||
item.background = it
|
||||
} else {
|
||||
it.setTint(highlightBorderColor)
|
||||
item.background = it
|
||||
}
|
||||
} ?: run {
|
||||
item.background = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
}
|
||||
is ImageButton -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
}
|
||||
is ThemeSelector -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
item.setHasFocus(true)
|
||||
}
|
||||
is BlockSkinSelector -> {
|
||||
item.background = GradientDrawable().apply {
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
item.setHasFocus(true)
|
||||
}
|
||||
is Switch -> {
|
||||
var gradientDrawable = GradientDrawable().apply {
|
||||
setColor(Color.TRANSPARENT)
|
||||
setStroke(borderWidth, highlightBorderColor)
|
||||
setCornerRadius(cornerRadius)
|
||||
}
|
||||
item.background = gradientDrawable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1857,6 +1887,11 @@ class MainActivity : AppCompatActivity(),
|
|||
selectedItem.confirmSelection()
|
||||
// The onBlockSkinSelected callback will handle updating the game view and saving the selection
|
||||
}
|
||||
is Switch -> {
|
||||
if (selectedItem.isEnabled) {
|
||||
selectedItem.isChecked = !selectedItem.isChecked
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
selectedItem.performClick()
|
||||
}
|
||||
|
|
9
app/src/main/res/drawable/menu_item_background.xml
Normal file
9
app/src/main/res/drawable/menu_item_background.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="#33FFFFFF" />
|
||||
<solid android:color="#1AFFFFFF" />
|
||||
</shape>
|
|
@ -691,6 +691,37 @@
|
|||
android:focusable="true"
|
||||
android:focusableInTouchMode="true" />
|
||||
|
||||
<!-- Random Mode Switch -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/menu_section_background"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/random_mode"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="sans-serif" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/randomModeSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Block Skin Selector -->
|
||||
<com.mintris.ui.BlockSkinSelector
|
||||
android:id="@+id/customizationBlockSkinSelector"
|
||||
|
|
|
@ -602,7 +602,38 @@
|
|||
<com.mintris.ui.BlockSkinSelector
|
||||
android:id="@+id/customizationBlockSkinSelector"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/menu_item_background"
|
||||
android:padding="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/randomModeContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="@drawable/menu_item_background"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/random_mode"
|
||||
android:textSize="18sp"
|
||||
android:textColor="@android:color/white" />
|
||||
|
||||
<Switch
|
||||
android:id="@+id/randomModeSwitch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleX="1.5"
|
||||
android:scaleY="1.5"
|
||||
android:thumbTint="@color/switch_thumb_color"
|
||||
android:trackTint="@color/switch_track_color" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Back Button -->
|
||||
<Button
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="black">#000000</color>
|
||||
<color name="white">#FFFFFF</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
<color name="gray_dark">#222222</color>
|
||||
<color name="gray_light">#CCCCCC</color>
|
||||
<color name="transparent">#00000000</color>
|
||||
<color name="switch_track_color">#33FFFFFF</color>
|
||||
<color name="switch_thumb_color">#FFFFFF</color>
|
||||
</resources>
|
|
@ -48,4 +48,5 @@
|
|||
<string name="reset_stats">reset stats</string>
|
||||
<string name="music">music</string>
|
||||
<string name="customization">Customization</string>
|
||||
<string name="random_mode">Random Mode</string>
|
||||
</resources>
|
Loading…
Add table
Add a link
Reference in a new issue