fix: ensure line clear callbacks are properly connected in GameView.setGameBoard()

This commit is contained in:
cmclark00 2025-03-27 00:54:04 -04:00
parent b068de76f5
commit 5016b6a2f3
4 changed files with 67 additions and 12 deletions

View file

@ -104,9 +104,18 @@ class MainActivity : AppCompatActivity() {
} }
gameView.onLineClear = { lineCount -> gameView.onLineClear = { lineCount ->
android.util.Log.d("MainActivity", "Received line clear callback: $lineCount lines")
// Use enhanced haptic feedback for line clears // Use enhanced haptic feedback for line clears
if (isSoundEnabled) { if (isSoundEnabled) {
gameHaptics.vibrateForLineClear(lineCount) android.util.Log.d("MainActivity", "Sound is enabled, triggering haptic feedback")
try {
gameHaptics.vibrateForLineClear(lineCount)
android.util.Log.d("MainActivity", "Haptic feedback triggered successfully")
} catch (e: Exception) {
android.util.Log.e("MainActivity", "Error triggering haptic feedback", e)
}
} else {
android.util.Log.d("MainActivity", "Sound is disabled, skipping haptic feedback")
} }
} }

View file

@ -27,27 +27,36 @@ class GameHaptics(private val context: Context) {
} }
fun vibrateForLineClear(lineCount: Int) { fun vibrateForLineClear(lineCount: Int) {
android.util.Log.d("GameHaptics", "Attempting to vibrate for $lineCount lines")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val duration = when (lineCount) { val duration = when (lineCount) {
4 -> 100L // Tetris 4 -> 200L // Tetris - doubled from 100L
3 -> 80L 3 -> 160L // Triples - doubled from 80L
2 -> 60L 2 -> 120L // Doubles - doubled from 60L
1 -> 40L 1 -> 80L // Singles - doubled from 40L
else -> 0L else -> 0L
} }
val amplitude = when (lineCount) { val amplitude = when (lineCount) {
4 -> VibrationEffect.DEFAULT_AMPLITUDE 4 -> 255 // Full amplitude for Tetris
3 -> (VibrationEffect.DEFAULT_AMPLITUDE * 0.8).toInt() 3 -> 230 // 90% amplitude for triples
2 -> (VibrationEffect.DEFAULT_AMPLITUDE * 0.6).toInt() 2 -> 180 // 70% amplitude for doubles
1 -> (VibrationEffect.DEFAULT_AMPLITUDE * 0.4).toInt() 1 -> 128 // 50% amplitude for singles
else -> 0 else -> 0
} }
android.util.Log.d("GameHaptics", "Vibration parameters - Duration: ${duration}ms, Amplitude: $amplitude")
if (duration > 0 && amplitude > 0) { if (duration > 0 && amplitude > 0) {
val vibrationEffect = VibrationEffect.createOneShot(duration, amplitude) try {
vibrator.vibrate(vibrationEffect) val vibrationEffect = VibrationEffect.createOneShot(duration, amplitude)
vibrator.vibrate(vibrationEffect)
android.util.Log.d("GameHaptics", "Vibration triggered successfully")
} catch (e: Exception) {
android.util.Log.e("GameHaptics", "Error triggering vibration", e)
}
} }
} else {
android.util.Log.w("GameHaptics", "Device does not support vibration effects (Android < 8.0)")
} }
} }

View file

@ -138,6 +138,15 @@ class GameView @JvmOverloads constructor(
// Connect our callbacks to the GameBoard // Connect our callbacks to the GameBoard
gameBoard.onPieceMove = { onPieceMove?.invoke() } gameBoard.onPieceMove = { onPieceMove?.invoke() }
gameBoard.onPieceLock = { onPieceLock?.invoke() } gameBoard.onPieceLock = { onPieceLock?.invoke() }
gameBoard.onLineClear = { lineCount ->
android.util.Log.d("GameView", "Received line clear from GameBoard: $lineCount lines")
try {
onLineClear?.invoke(lineCount)
android.util.Log.d("GameView", "Forwarded line clear callback")
} catch (e: Exception) {
android.util.Log.e("GameView", "Error forwarding line clear callback", e)
}
}
// Force hardware acceleration - This is critical for performance // Force hardware acceleration - This is critical for performance
setLayerType(LAYER_TYPE_HARDWARE, null) setLayerType(LAYER_TYPE_HARDWARE, null)
@ -560,6 +569,20 @@ class GameView @JvmOverloads constructor(
*/ */
fun setGameBoard(board: GameBoard) { fun setGameBoard(board: GameBoard) {
gameBoard = board gameBoard = board
// Reconnect callbacks to the new board
gameBoard.onPieceMove = { onPieceMove?.invoke() }
gameBoard.onPieceLock = { onPieceLock?.invoke() }
gameBoard.onLineClear = { lineCount ->
android.util.Log.d("GameView", "Received line clear from GameBoard: $lineCount lines")
try {
onLineClear?.invoke(lineCount)
android.util.Log.d("GameView", "Forwarded line clear callback")
} catch (e: Exception) {
android.util.Log.e("GameView", "Error forwarding line clear callback", e)
}
}
invalidate() invalidate()
} }

View file

@ -49,6 +49,7 @@ class GameBoard(
var onPieceMove: (() -> Unit)? = null var onPieceMove: (() -> Unit)? = null
var onPieceLock: (() -> Unit)? = null var onPieceLock: (() -> Unit)? = null
var onNextPieceChanged: (() -> Unit)? = null var onNextPieceChanged: (() -> Unit)? = null
var onLineClear: ((Int) -> Unit)? = null
init { init {
spawnNextPiece() spawnNextPiece()
@ -299,8 +300,21 @@ class GameBoard(
java.util.Arrays.fill(grid[y], false) java.util.Arrays.fill(grid[y], false)
} }
// If lines were cleared, calculate score in background // If lines were cleared, calculate score in background and trigger callback
if (shiftAmount > 0) { if (shiftAmount > 0) {
android.util.Log.d("GameBoard", "Lines cleared: $shiftAmount")
// Trigger line clear callback on main thread
val mainHandler = android.os.Handler(android.os.Looper.getMainLooper())
mainHandler.post {
android.util.Log.d("GameBoard", "Triggering onLineClear callback with $shiftAmount lines")
try {
onLineClear?.invoke(shiftAmount)
android.util.Log.d("GameBoard", "onLineClear callback completed successfully")
} catch (e: Exception) {
android.util.Log.e("GameBoard", "Error in onLineClear callback", e)
}
}
Thread { Thread {
calculateScore(shiftAmount) calculateScore(shiftAmount)
}.start() }.start()