Adjusted horizontal sprite shake timing to sync with attack hit.

This commit is contained in:
lightheel 2025-08-06 19:19:58 -04:00
parent 5bb9fe5209
commit 61a2439f84
2 changed files with 137 additions and 9 deletions

View File

@ -5,6 +5,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.State
class ArenaBattleSystem {
companion object {
@ -85,6 +86,20 @@ class ArenaBattleSystem {
private var _isOpponentHit by mutableStateOf(false)
val isOpponentHit: Boolean get() = _isOpponentHit
// Delayed hit states for SLEEP animation timing
private var _isPlayerHitDelayed by mutableStateOf(false)
val isPlayerHitDelayed: Boolean get() = _isPlayerHitDelayed
private var _isOpponentHitDelayed by mutableStateOf(false)
val isOpponentHitDelayed: Boolean get() = _isOpponentHitDelayed
// Delayed shake states for shake animation timing
private var _isPlayerShakeDelayed by mutableStateOf(false)
val isPlayerShakeDelayed: Boolean get() = _isPlayerShakeDelayed
private var _isOpponentShakeDelayed by mutableStateOf(false)
val isOpponentShakeDelayed: Boolean get() = _isOpponentShakeDelayed
// Counter-attack tracking
private var _shouldCounterAttack by mutableStateOf(false)
val shouldCounterAttack: Boolean get() = _shouldCounterAttack
@ -187,6 +202,10 @@ class ArenaBattleSystem {
_opponentDodgeDirection = 1f
_isPlayerHit = false
_isOpponentHit = false
_isPlayerHitDelayed = false
_isOpponentHitDelayed = false
_isPlayerShakeDelayed = false
_isOpponentShakeDelayed = false
_shouldCounterAttack = false
_counterAttackIsHit = false
_opponentAttackIsHit = false
@ -297,12 +316,22 @@ class ArenaBattleSystem {
Log.d(TAG, "Started player hit animation")
}
fun startPlayerHitDelayed() {
_isPlayerHitDelayed = true
Log.d(TAG, "Started delayed player hit animation")
}
fun endPlayerHit() {
_isPlayerHit = false
_hitProgress = 0f
Log.d(TAG, "Ended player hit animation")
}
fun endPlayerHitDelayed() {
_isPlayerHitDelayed = false
Log.d(TAG, "Ended delayed player hit animation")
}
// Opponent-specific hit methods
fun startOpponentHit() {
_isOpponentHit = true
@ -310,12 +339,43 @@ class ArenaBattleSystem {
Log.d(TAG, "Started opponent hit animation")
}
fun startOpponentHitDelayed() {
_isOpponentHitDelayed = true
Log.d(TAG, "Started delayed opponent hit animation")
}
fun endOpponentHit() {
_isOpponentHit = false
_hitProgress = 0f
Log.d(TAG, "Ended opponent hit animation")
}
fun endOpponentHitDelayed() {
_isOpponentHitDelayed = false
Log.d(TAG, "Ended delayed opponent hit animation")
}
// Delayed shake methods
fun startPlayerShakeDelayed() {
_isPlayerShakeDelayed = true
Log.d(TAG, "Started delayed player shake animation")
}
fun endPlayerShakeDelayed() {
_isPlayerShakeDelayed = false
Log.d(TAG, "Ended delayed player shake animation")
}
fun startOpponentShakeDelayed() {
_isOpponentShakeDelayed = true
Log.d(TAG, "Started delayed opponent shake animation")
}
fun endOpponentShakeDelayed() {
_isOpponentShakeDelayed = false
Log.d(TAG, "Ended delayed opponent shake animation")
}
// Combined method to handle attack result
fun handleAttackResult(isHit: Boolean) {
_attackIsHit = isHit

View File

@ -179,7 +179,11 @@ fun BattleScreen(
showOpponentHitEffect = false
hidePlayerAttackSprite = false
hideEnemyAttackSprite = false
println("DEBUG: Reset hit effect states - attack phase returned to idle")
battleSystem.endPlayerHitDelayed()
battleSystem.endOpponentHitDelayed()
battleSystem.endPlayerShakeDelayed()
battleSystem.endOpponentShakeDelayed()
println("DEBUG: Reset hit effect states, attack sprite visibility, and delayed hit states")
}
}
@ -240,6 +244,18 @@ fun BattleScreen(
println("DEBUG: Showing opponent damage number after delay")
}
}
// Delay SLEEP animation to match hit effect timing
coroutineScope.launch {
delay(400) // Match the hit effect delay
battleSystem.startOpponentHitDelayed()
println("DEBUG: Starting delayed opponent hit animation")
}
// Delay shake animation to match hit effect timing
coroutineScope.launch {
delay(400) // Match the hit effect delay
battleSystem.startOpponentShakeDelayed()
println("DEBUG: Starting delayed opponent shake animation")
}
} else {
// Player attack misses, enemy dodges
println("Player attack misses, enemy dodges at progress $progress")
@ -305,6 +321,18 @@ fun BattleScreen(
println("DEBUG: Showing player damage number after delay")
}
}
// Delay SLEEP animation to match hit effect timing
coroutineScope.launch {
delay(400) // Match the hit effect delay
battleSystem.startPlayerHitDelayed()
println("DEBUG: Starting delayed player hit animation")
}
// Delay shake animation to match hit effect timing
coroutineScope.launch {
delay(400) // Match the hit effect delay
battleSystem.startPlayerShakeDelayed()
println("DEBUG: Starting delayed player shake animation")
}
} else {
// Enemy attack misses, player dodges
println("Enemy attack misses, player dodges at progress $progress")
@ -424,6 +452,26 @@ fun BattleScreen(
}
}
// Player delayed shake animation
LaunchedEffect(battleSystem.isPlayerShakeDelayed) {
if (battleSystem.isPlayerShakeDelayed) {
println("Starting delayed player shake animation")
var hitProgress = 0f
// Quick hit effect
while (hitProgress < 1f) {
hitProgress += 0.1f // Fast hit effect
battleSystem.setHitProgress(hitProgress)
delay(16)
}
delay(100) // Brief pause
battleSystem.endPlayerShakeDelayed()
println("Delayed player shake animation completed")
}
}
// Opponent hit animation
LaunchedEffect(battleSystem.isOpponentHit) {
if (battleSystem.isOpponentHit) {
@ -444,6 +492,26 @@ fun BattleScreen(
}
}
// Opponent delayed shake animation
LaunchedEffect(battleSystem.isOpponentShakeDelayed) {
if (battleSystem.isOpponentShakeDelayed) {
println("Starting delayed opponent shake animation")
var hitProgress = 0f
// Quick hit effect
while (hitProgress < 1f) {
hitProgress += 0.1f // Fast hit effect
battleSystem.setHitProgress(hitProgress)
delay(16)
}
delay(100) // Brief pause
battleSystem.endOpponentShakeDelayed()
println("Delayed opponent shake animation completed")
}
}
// Damage number handling - store pending damage but don't show immediately
LaunchedEffect(pendingPlayerDamage) {
if (pendingPlayerDamage > 0) {
@ -721,7 +789,7 @@ fun MiddleBattleView(
val enemyAnimationType = when {
battleSystem.attackPhase == 1 -> DigimonAnimationType.ATTACK // Both attacking in Phase 1
battleSystem.isOpponentDodging -> DigimonAnimationType.WALK
battleSystem.isOpponentHit -> DigimonAnimationType.SLEEP
battleSystem.isOpponentHitDelayed -> DigimonAnimationType.SLEEP
else -> DigimonAnimationType.IDLE
}
@ -741,7 +809,7 @@ fun MiddleBattleView(
}
// Calculate hit effect for enemy
val enemyHitOffset = if (battleSystem.isOpponentHit) {
val enemyHitOffset = if (battleSystem.isOpponentShakeDelayed) {
val shakeAmount = 5.dp
val progress = battleSystem.hitProgress
val shake = if (progress < 0.5f) progress * 2f else (1f - progress) * 2f
@ -802,7 +870,7 @@ fun MiddleBattleView(
val playerAnimationType = when {
battleSystem.attackPhase == 1 -> DigimonAnimationType.ATTACK // Both attacking in Phase 1
battleSystem.isPlayerDodging -> DigimonAnimationType.WALK
battleSystem.isPlayerHit -> DigimonAnimationType.SLEEP
battleSystem.isPlayerHitDelayed -> DigimonAnimationType.SLEEP
else -> DigimonAnimationType.IDLE
}
@ -822,7 +890,7 @@ fun MiddleBattleView(
}
// Calculate hit effect for player
val playerHitOffset = if (battleSystem.isPlayerHit) {
val playerHitOffset = if (battleSystem.isPlayerShakeDelayed) {
val shakeAmount = 5.dp
val progress = battleSystem.hitProgress
val shake = if (progress < 0.5f) progress * 2f else (1f - progress) * 2f
@ -1135,7 +1203,7 @@ fun PlayerBattleView(
// Determine animation type based on battle state
val animationType = when {
battleSystem.isPlayerDodging -> DigimonAnimationType.WALK // Use walk animation for dodge
battleSystem.isPlayerHit -> DigimonAnimationType.SLEEP // Use sleep animation for hit effect (injured sprite)
battleSystem.isPlayerHitDelayed -> DigimonAnimationType.SLEEP // Use sleep animation for hit effect (injured sprite)
battleSystem.attackPhase == 1 -> DigimonAnimationType.ATTACK // Player attack on player screen
battleSystem.attackPhase == 2 -> DigimonAnimationType.ATTACK // Player attack on opponent screen
battleSystem.attackPhase == 3 -> DigimonAnimationType.IDLE // Opponent attack on opponent screen
@ -1161,7 +1229,7 @@ fun PlayerBattleView(
}
// Calculate hit effect (slight shake)
val hitOffset = if (battleSystem.isPlayerHit) {
val hitOffset = if (battleSystem.isPlayerShakeDelayed) {
val shakeAmount = 5.dp
val progress = battleSystem.hitProgress
// Simple shake effect without complex math
@ -1448,7 +1516,7 @@ fun EnemyBattleView(
// Determine animation type based on battle state
val animationType = when {
battleSystem.isOpponentDodging -> DigimonAnimationType.WALK // Use walk animation for dodge
battleSystem.isOpponentHit -> DigimonAnimationType.SLEEP // Use sleep animation for hit effect (injured sprite)
battleSystem.isOpponentHitDelayed -> DigimonAnimationType.SLEEP // Use sleep animation for hit effect (injured sprite)
battleSystem.attackPhase == 2 -> DigimonAnimationType.IDLE // Player attack on enemy screen
else -> DigimonAnimationType.IDLE
}
@ -1471,7 +1539,7 @@ fun EnemyBattleView(
}
// Calculate hit effect (slight shake)
val hitOffset = if (battleSystem.isOpponentHit) {
val hitOffset = if (battleSystem.isOpponentShakeDelayed) {
val shakeAmount = 5.dp
val progress = battleSystem.hitProgress
// Simple shake effect without complex math