mirror of
https://github.com/nacabaro/vbhelper.git
synced 2026-06-05 13:52:54 +00:00
Offset idle animation so player/enemy Digimon aren't in sync.
This commit is contained in:
parent
d833a89c17
commit
371a850d45
@ -7,6 +7,7 @@ import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Composable
|
||||
fun AnimatedSpriteImage(
|
||||
@ -14,11 +15,22 @@ fun AnimatedSpriteImage(
|
||||
animationType: DigimonAnimationType = DigimonAnimationType.IDLE,
|
||||
modifier: Modifier = Modifier,
|
||||
contentScale: ContentScale = ContentScale.Fit,
|
||||
reloadMappings: Boolean = false
|
||||
reloadMappings: Boolean = false,
|
||||
animationOffset: Long = 0L // New parameter for offsetting animation timing
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val spriteManager = remember { IndividualSpriteManager(context) }
|
||||
val animationStateMachine = remember { DigimonAnimationStateMachine(characterId, context) }
|
||||
|
||||
// Calculate frame offset based on animation offset
|
||||
// 750ms is the idle animation duration, so we calculate how many frames to offset
|
||||
val frameOffset = if (animationOffset > 0L) {
|
||||
// Convert time offset to frame offset (2 frames per cycle, 750ms per frame)
|
||||
((animationOffset / 750L) * 2).toInt()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
val animationStateMachine = remember { DigimonAnimationStateMachine(characterId, context, frameOffset, animationOffset) }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
var bitmap by remember { mutableStateOf<android.graphics.Bitmap?>(null) }
|
||||
|
||||
@ -31,7 +31,9 @@ data class AnimationState(
|
||||
|
||||
class DigimonAnimationStateMachine(
|
||||
private val characterId: String,
|
||||
private val context: Context
|
||||
private val context: Context,
|
||||
private val initialFrameOffset: Int = 0, // New parameter for offsetting the starting frame
|
||||
private val timingOffset: Long = 0L // New parameter for offsetting the timing
|
||||
) {
|
||||
var currentAnimation by mutableStateOf<DigimonAnimationType>(DigimonAnimationType.IDLE)
|
||||
private set
|
||||
@ -79,7 +81,7 @@ class DigimonAnimationStateMachine(
|
||||
)
|
||||
|
||||
init {
|
||||
println("Initialized DigimonAnimationStateMachine for character: $characterId")
|
||||
println("Initialized DigimonAnimationStateMachine for character: $characterId with frame offset: $initialFrameOffset, timing offset: $timingOffset")
|
||||
println("Available animation types: ${animationTypeToFrames.keys}")
|
||||
}
|
||||
|
||||
@ -128,12 +130,17 @@ class DigimonAnimationStateMachine(
|
||||
// Combine frames for cycling idle animation
|
||||
val combinedFrames = (idleFrames + idle2Frames).distinct()
|
||||
|
||||
println("Playing idle animation with frames: $combinedFrames")
|
||||
println("Playing idle animation with frames: $combinedFrames, starting at offset: $initialFrameOffset, timing offset: $timingOffset")
|
||||
|
||||
val duration = animationDurations[DigimonAnimationType.IDLE] ?: 500L
|
||||
|
||||
// Cycle through idle frames
|
||||
var frameIndex = 0
|
||||
// Apply initial timing offset
|
||||
if (timingOffset > 0L) {
|
||||
delay(timingOffset)
|
||||
}
|
||||
|
||||
// Cycle through idle frames, starting from the offset
|
||||
var frameIndex = initialFrameOffset
|
||||
while (isPlaying && currentAnimation == DigimonAnimationType.IDLE) {
|
||||
val frameNumber = combinedFrames[frameIndex % combinedFrames.size]
|
||||
currentFrameNumber = frameNumber
|
||||
|
||||
@ -730,7 +730,8 @@ fun MiddleBattleView(
|
||||
y = enemyVerticalOffset + 40.dp
|
||||
),
|
||||
contentScale = ContentScale.Fit,
|
||||
reloadMappings = false
|
||||
reloadMappings = false,
|
||||
animationOffset = 375L // Offset enemy animation by half the idle duration
|
||||
)
|
||||
|
||||
// Enemy attack sprite (Phase 1 only)
|
||||
@ -811,7 +812,8 @@ fun MiddleBattleView(
|
||||
y = playerVerticalOffset - 40.dp
|
||||
),
|
||||
contentScale = ContentScale.Fit,
|
||||
reloadMappings = false
|
||||
reloadMappings = false,
|
||||
animationOffset = 0L // Player animation starts immediately
|
||||
)
|
||||
|
||||
// Player attack sprite (Phase 1 only)
|
||||
@ -1149,7 +1151,8 @@ fun PlayerBattleView(
|
||||
y = verticalOffset
|
||||
),
|
||||
contentScale = ContentScale.Fit,
|
||||
reloadMappings = false
|
||||
reloadMappings = false,
|
||||
animationOffset = 0L // Player animation starts immediately
|
||||
)
|
||||
|
||||
// Attack sprite visibility and positioning based on attack phase
|
||||
@ -1456,7 +1459,8 @@ fun EnemyBattleView(
|
||||
y = verticalOffset
|
||||
),
|
||||
contentScale = ContentScale.Fit,
|
||||
reloadMappings = false
|
||||
reloadMappings = false,
|
||||
animationOffset = 375L // Offset enemy animation by half the idle duration
|
||||
)
|
||||
|
||||
// Attack sprite visibility and positioning based on attack phase
|
||||
@ -1797,7 +1801,8 @@ fun BattlesScreen() {
|
||||
animationType = currentTestAnimation,
|
||||
modifier = Modifier.size(120.dp),
|
||||
contentScale = ContentScale.Fit,
|
||||
reloadMappings = false
|
||||
reloadMappings = false,
|
||||
animationOffset = 0L // No offset for sprite tester
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user