Fix: Play game over sound with animation start

This commit is contained in:
cmclark00 2025-04-01 15:21:03 -04:00
parent ff0ef4b2a7
commit 301bf1e64f
2 changed files with 64 additions and 33 deletions

View file

@ -84,8 +84,6 @@ class MainActivity : AppCompatActivity(),
private var pauseMenuScrollView: ScrollView? = null private var pauseMenuScrollView: ScrollView? = null
// Game state // Game state
private var isSoundEnabled = true
private var isMusicEnabled = true
private var piecesPlaced = 0 private var piecesPlaced = 0
private var gameStartTime = 0L private var gameStartTime = 0L
private var selectedLevel = 1 private var selectedLevel = 1
@ -232,6 +230,17 @@ class MainActivity : AppCompatActivity(),
binding.currentLevelText.text = newLevel.toString() binding.currentLevelText.text = newLevel.toString()
}) })
// Observe Sound/Music state
viewModel.isSoundEnabled.observe(this, Observer { enabled ->
updateSoundToggleUI(enabled)
})
viewModel.isMusicEnabled.observe(this, Observer { enabled ->
updateMusicToggleUI(enabled)
// Also update GameMusic immediately
gameMusic.setEnabled(enabled)
})
// Load random mode setting // Load random mode setting
isRandomModeEnabled = getSharedPreferences("com.com.pixelmintgames.pixelmintdrop.preferences", Context.MODE_PRIVATE) isRandomModeEnabled = getSharedPreferences("com.com.pixelmintgames.pixelmintdrop.preferences", Context.MODE_PRIVATE)
.getBoolean("random_mode_enabled", false) .getBoolean("random_mode_enabled", false)
@ -354,9 +363,8 @@ class MainActivity : AppCompatActivity(),
// Set up music toggle // Set up music toggle
binding.musicToggle.setOnClickListener { binding.musicToggle.setOnClickListener {
isMusicEnabled = !isMusicEnabled viewModel.toggleMusic() // Use ViewModel
gameMusic.setEnabled(isMusicEnabled) // Observer will call updateMusicToggleUI and gameMusic.setEnabled
updateMusicToggleUI()
} }
// Set up callbacks // Set up callbacks
@ -365,9 +373,12 @@ class MainActivity : AppCompatActivity(),
} }
gameView.onGameOver = { finalScore -> gameView.onGameOver = { finalScore ->
// Start animation & pause music // Start animation & pause music & play sound
gameView.startGameOverAnimation() gameView.startGameOverAnimation()
gameMusic.pause() gameMusic.pause()
if (viewModel.isSoundEnabled.value == true) { // Play sound if enabled
gameMusic.playGameOver()
}
// Calculate final stats, XP, and high score // Calculate final stats, XP, and high score
val timePlayedMs = System.currentTimeMillis() - gameStartTime val timePlayedMs = System.currentTimeMillis() - gameStartTime
@ -405,7 +416,7 @@ class MainActivity : AppCompatActivity(),
gameView.onLineClear = { lineCount -> gameView.onLineClear = { lineCount ->
Log.d(TAG, "Received line clear callback: $lineCount lines") Log.d(TAG, "Received line clear callback: $lineCount lines")
// Use enhanced haptic feedback for line clears // Use enhanced haptic feedback for line clears
if (isSoundEnabled) { if (viewModel.isSoundEnabled.value == true) { // Read from ViewModel
Log.d(TAG, "Sound is enabled, triggering haptic feedback") Log.d(TAG, "Sound is enabled, triggering haptic feedback")
try { try {
gameHaptics.vibrateForLineClear(lineCount) gameHaptics.vibrateForLineClear(lineCount)
@ -422,7 +433,7 @@ class MainActivity : AppCompatActivity(),
// Add callbacks for piece movement and locking // Add callbacks for piece movement and locking
gameView.onPieceMove = { gameView.onPieceMove = {
if (isSoundEnabled) { if (viewModel.isSoundEnabled.value == true) { // Read from ViewModel
gameHaptics.vibrateForPieceMove() gameHaptics.vibrateForPieceMove()
} }
} }
@ -443,7 +454,8 @@ class MainActivity : AppCompatActivity(),
binding.settingsButton.setOnClickListener { binding.settingsButton.setOnClickListener {
gameHaptics.performHapticFeedback(it, HapticFeedbackConstants.VIRTUAL_KEY) gameHaptics.performHapticFeedback(it, HapticFeedbackConstants.VIRTUAL_KEY)
toggleSound() viewModel.toggleSound() // Use ViewModel
// Observer will call updateSoundToggleUI
} }
// Set up pause menu buttons // Set up pause menu buttons
@ -569,11 +581,6 @@ class MainActivity : AppCompatActivity(),
// Make the container visible // Make the container visible
binding.gameOverContainer.visibility = View.VISIBLE binding.gameOverContainer.visibility = View.VISIBLE
// Play game over sound if not already played by progression
if (isSoundEnabled && progressionScreen.visibility != View.VISIBLE) {
gameMusic.playGameOver()
}
// Vibrate if not already vibrated by progression // Vibrate if not already vibrated by progression
if (progressionScreen.visibility != View.VISIBLE) { if (progressionScreen.visibility != View.VISIBLE) {
vibrate(VibrationEffect.EFFECT_DOUBLE_CLICK) vibrate(VibrationEffect.EFFECT_DOUBLE_CLICK)
@ -824,19 +831,6 @@ class MainActivity : AppCompatActivity(),
binding.pauseContainer.visibility = View.GONE binding.pauseContainer.visibility = View.GONE
} }
/**
* Toggle sound on/off
*/
private fun toggleSound() {
isSoundEnabled = !isSoundEnabled
binding.settingsButton.text = getString(
if (isSoundEnabled) R.string.sound_on else R.string.sound_off
)
// Vibrate to provide feedback
vibrate(VibrationEffect.EFFECT_CLICK)
}
/** /**
* Update the level selector display * Update the level selector display
*/ */
@ -862,9 +856,21 @@ class MainActivity : AppCompatActivity(),
} }
} }
private fun updateMusicToggleUI() { /**
* Update the sound toggle button text
*/
private fun updateSoundToggleUI(enabled: Boolean) {
binding.settingsButton.text = getString(
if (enabled) R.string.sound_on else R.string.sound_off
)
}
/**
* Update the music toggle button icon
*/
private fun updateMusicToggleUI(enabled: Boolean) {
binding.musicToggle.setImageResource( binding.musicToggle.setImageResource(
if (isMusicEnabled) R.drawable.ic_volume_up if (enabled) R.drawable.ic_volume_up
else R.drawable.ic_volume_off else R.drawable.ic_volume_off
) )
} }
@ -923,9 +929,12 @@ class MainActivity : AppCompatActivity(),
} }
gameView.onGameOver = { finalScore -> gameView.onGameOver = { finalScore ->
// Start animation & pause music // Start animation & pause music & play sound
gameView.startGameOverAnimation() gameView.startGameOverAnimation()
gameMusic.pause() gameMusic.pause()
if (viewModel.isSoundEnabled.value == true) { // Play sound if enabled
gameMusic.playGameOver()
}
// Calculate final stats, XP, and high score // Calculate final stats, XP, and high score
val timePlayedMs = System.currentTimeMillis() - gameStartTime val timePlayedMs = System.currentTimeMillis() - gameStartTime
@ -977,13 +986,13 @@ class MainActivity : AppCompatActivity(),
binding.resumeButton.visibility = View.GONE binding.resumeButton.visibility = View.GONE
// Start background music if enabled // Start background music if enabled
if (isMusicEnabled) { if (viewModel.isMusicEnabled.value == true) { // Read from ViewModel
gameMusic.start() gameMusic.start()
} }
// Start the game // Start the game
gameView.start() gameView.start()
gameMusic.setEnabled(isMusicEnabled) // Observer ensures gameMusic is enabled/disabled correctly via gameMusic.setEnabled()
// Reset session stats // Reset session stats
statsManager.startNewSession() statsManager.startNewSession()
@ -1000,7 +1009,7 @@ class MainActivity : AppCompatActivity(),
private fun resumeGame() { private fun resumeGame() {
gameView.resume() gameView.resume()
if (isMusicEnabled) { if (viewModel.isMusicEnabled.value == true) { // Read from ViewModel
gameMusic.resume() gameMusic.resume()
} }
// Force a redraw to ensure pieces aren't frozen // Force a redraw to ensure pieces aren't frozen

View file

@ -14,6 +14,14 @@ class MainActivityViewModel : ViewModel() {
val currentScore: LiveData<Long> = _currentScore val currentScore: LiveData<Long> = _currentScore
val currentLevel: LiveData<Int> = _currentLevel val currentLevel: LiveData<Int> = _currentLevel
// --- Sound & Music State ---
private val _isSoundEnabled = MutableLiveData<Boolean>(true) // Default to true
val isSoundEnabled: LiveData<Boolean> = _isSoundEnabled
private val _isMusicEnabled = MutableLiveData<Boolean>(true) // Default to true
val isMusicEnabled: LiveData<Boolean> = _isMusicEnabled
// ---------------------------
// Example function to update the score (logic would be moved here) // Example function to update the score (logic would be moved here)
fun incrementScore(points: Long) { fun incrementScore(points: Long) {
_currentScore.value = (_currentScore.value ?: 0L) + points _currentScore.value = (_currentScore.value ?: 0L) + points
@ -36,5 +44,19 @@ class MainActivityViewModel : ViewModel() {
// Reset other game state within the ViewModel as needed // Reset other game state within the ViewModel as needed
} }
// --- Sound & Music Logic ---
fun toggleSound() {
_isSoundEnabled.value = !(_isSoundEnabled.value ?: true)
}
fun setMusicEnabled(enabled: Boolean) {
_isMusicEnabled.value = enabled
}
fun toggleMusic() {
setMusicEnabled(!(_isMusicEnabled.value ?: true))
}
// --------------------------
// Add other state variables and logic related to game state here // Add other state variables and logic related to game state here
} }