Add background music and fix pause menu: - Add GameMusic class for background music playback - Add music toggle button to UI - Fix resume button to properly resume game instead of restarting - Add volume control icons - Add proper music lifecycle management

This commit is contained in:
cmclark00 2025-03-26 16:52:22 -04:00
parent fabb2742da
commit a56f08afb9
7 changed files with 172 additions and 7 deletions

View file

@ -17,6 +17,7 @@ import com.mintris.game.GameView
import com.mintris.game.NextPieceView
import android.view.HapticFeedbackConstants
import com.mintris.model.GameBoard
import com.mintris.audio.GameMusic
class MainActivity : AppCompatActivity() {
@ -25,9 +26,11 @@ class MainActivity : AppCompatActivity() {
private lateinit var gameView: GameView
private lateinit var gameHaptics: GameHaptics
private lateinit var gameBoard: GameBoard
private lateinit var gameMusic: GameMusic
// Game state
private var isSoundEnabled = true
private var isMusicEnabled = true
private var selectedLevel = 1
private val maxLevel = 20
@ -40,6 +43,7 @@ class MainActivity : AppCompatActivity() {
gameBoard = GameBoard()
gameHaptics = GameHaptics(this)
gameView = binding.gameView
gameMusic = GameMusic(this)
// Set up game view
gameView.setGameBoard(gameBoard)
@ -51,6 +55,13 @@ class MainActivity : AppCompatActivity() {
binding.nextPieceView.invalidate()
}
// Set up music toggle
binding.musicToggle.setOnClickListener {
isMusicEnabled = !isMusicEnabled
gameMusic.setEnabled(isMusicEnabled)
updateMusicToggleUI()
}
// Start game immediately
startGame()
@ -94,7 +105,7 @@ class MainActivity : AppCompatActivity() {
binding.resumeButton.setOnClickListener {
gameHaptics.performHapticFeedback(it, HapticFeedbackConstants.VIRTUAL_KEY)
hidePauseMenu()
gameView.start()
resumeGame()
}
binding.settingsButton.setOnClickListener {
@ -217,11 +228,19 @@ class MainActivity : AppCompatActivity() {
vibrator.vibrate(VibrationEffect.createPredefined(effectId))
}
private fun updateMusicToggleUI() {
binding.musicToggle.setImageResource(
if (isMusicEnabled) R.drawable.ic_volume_up
else R.drawable.ic_volume_off
)
}
private fun startGame() {
gameView.visibility = View.VISIBLE
gameBoard.startGame()
gameView.start()
hidePauseMenu()
gameMusic.setEnabled(isMusicEnabled) // Explicitly set enabled state
if (isMusicEnabled) {
gameMusic.start()
}
}
private fun restartGame() {
@ -231,10 +250,22 @@ class MainActivity : AppCompatActivity() {
showPauseMenu()
}
private fun pauseGame() {
gameView.pause()
gameMusic.pause()
}
private fun resumeGame() {
gameView.resume()
if (isMusicEnabled) {
gameMusic.start()
}
}
override fun onPause() {
super.onPause()
if (!gameView.isGameOver()) {
gameView.pause()
pauseGame()
showPauseMenu()
binding.pauseStartButton.visibility = View.GONE
binding.resumeButton.visibility = View.VISIBLE
@ -256,12 +287,19 @@ class MainActivity : AppCompatActivity() {
binding.resumeButton.visibility = View.VISIBLE
} else {
hidePauseMenu()
gameView.start()
resumeGame()
}
}
override fun onResume() {
super.onResume()
gameView.resume()
if (!gameView.isGameOver()) {
resumeGame()
}
}
override fun onDestroy() {
super.onDestroy()
gameMusic.release()
}
}

View file

@ -0,0 +1,93 @@
package com.mintris.audio
import android.content.Context
import android.media.MediaPlayer
import android.media.AudioAttributes
import android.os.Build
import android.util.Log
import com.mintris.R
class GameMusic(private val context: Context) {
private var mediaPlayer: MediaPlayer? = null
private var isEnabled = false
init {
setupMediaPlayer()
}
private fun setupMediaPlayer() {
try {
Log.d("GameMusic", "Setting up MediaPlayer")
mediaPlayer = MediaPlayer.create(context, R.raw.game_music).apply {
isLooping = true
setVolume(0.5f, 0.5f)
// Set audio attributes for better performance
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
)
}
}
Log.d("GameMusic", "MediaPlayer setup complete")
} catch (e: Exception) {
Log.e("GameMusic", "Error setting up MediaPlayer", e)
}
}
fun start() {
try {
Log.d("GameMusic", "Starting music playback, isEnabled: $isEnabled")
if (isEnabled && mediaPlayer?.isPlaying != true) {
mediaPlayer?.start()
Log.d("GameMusic", "Music playback started")
}
} catch (e: Exception) {
Log.e("GameMusic", "Error starting music", e)
}
}
fun pause() {
try {
Log.d("GameMusic", "Pausing music playback")
mediaPlayer?.pause()
} catch (e: Exception) {
Log.e("GameMusic", "Error pausing music", e)
}
}
fun stop() {
try {
Log.d("GameMusic", "Stopping music playback")
mediaPlayer?.stop()
mediaPlayer?.prepare()
} catch (e: Exception) {
Log.e("GameMusic", "Error stopping music", e)
}
}
fun setEnabled(enabled: Boolean) {
Log.d("GameMusic", "Setting music enabled: $enabled")
isEnabled = enabled
if (enabled) {
start()
} else {
pause()
}
}
fun isEnabled(): Boolean = isEnabled
fun release() {
try {
Log.d("GameMusic", "Releasing MediaPlayer")
mediaPlayer?.release()
mediaPlayer = null
} catch (e: Exception) {
Log.e("GameMusic", "Error releasing MediaPlayer", e)
}
}
}