From 2e7389665978f8c80bfaf4c86e44636b1a034b18 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 12 Jun 2020 17:08:06 +0200 Subject: [PATCH] Make the code for pot distribution animation --- .../android/model/handhistory/Street.kt | 2 + .../handhistory/model/ComputedAction.kt | 2 +- .../modules/handhistory/replayer/HandStep.kt | 17 +++- .../replayer/ReplayerConfiguration.kt | 79 ++++++++++----- .../handhistory/replayer/TableDrawer.kt | 96 ++++++++++--------- 5 files changed, 127 insertions(+), 69 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt index 90df7fff..8180e71e 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt @@ -13,6 +13,8 @@ enum class Street : HandStep { RIVER, SUMMARY; + override val street: Street = this + val totalBoardCards: Int get() { return when (this) { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt index 0009f1c7..ba9ae32d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt @@ -300,7 +300,7 @@ class ComputedAction(var manager: ActionManager, /*** * Shortcut to return the action street */ - val street: Street + override val street: Street get() { return this.action.street } override val viewType: Int = HandRowType.ACTION.ordinal diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt index 0d570786..948d4af5 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt @@ -6,11 +6,23 @@ import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList + + interface HandStep { - fun frames(configuration: ReplayerConfiguration, canvas: Canvas, context: Context, update: () -> (Unit)) + val street: Street -// fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) +// abstract class Animation(override val street: Street) : HandStep { +// override fun frames(configuration: ReplayerConfiguration, canvas: Canvas, context: Context, update: () -> Unit) { +// TODO("Not yet implemented") +// } +// } +// +// class GatherChips(street: Street) : Animation(street) +// +// class DistributeChips(street: Street) : Animation(street) + + fun frames(configuration: ReplayerConfiguration, canvas: Canvas, context: Context, update: () -> (Unit)) companion object { @@ -27,6 +39,7 @@ interface HandStep { for (action in streetActions) { steps.add(action) } + } return steps } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt index 2e73c8e6..8cf4faa3 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt @@ -11,27 +11,49 @@ import kotlin.math.max class ReplayerConfiguration(var handHistory: HandHistory) { + enum class FrameType { + STATE, + GATHER_ANIMATION, + DISTRIBUTION_ANIMATION + } + private val animationFramesPerSecond = 60 val animationRate: Long get() { return 1000L / this.animationFramesPerSecond} private val animationDuration = 200L - private val framesForStreetAnimation: Int + private val framesForChipsAnimation: Int get() { return (animationDuration / animationRate).toInt() } private val numberOfFramesForCurrentStep: Int get() { - return when (val step = this.steps[this.stepIndex]) { - is Street -> framesForStreetAnimation + 1 + return when (val step = this.currentStep) { is ComputedAction -> 1 + Street.SUMMARY -> 1 + 2 * framesForChipsAnimation // 2 animations + is Street -> 1 + framesForChipsAnimation else -> throw PAIllegalStateException("unmanaged step: $step") } } private var currentFrame = 0 - val isLastFrame: Boolean - get() { return this.currentFrame == numberOfFramesForCurrentStep - 1 } + val frameType: FrameType + get() { + return when (val step = this.currentStep) { + is ComputedAction -> FrameType.STATE + is Street -> { + when (this.currentFrame) { + in (0 until framesForChipsAnimation) -> FrameType.GATHER_ANIMATION + framesForChipsAnimation -> FrameType.STATE + else -> FrameType.DISTRIBUTION_ANIMATION + } + } + else -> throw PAIllegalStateException("unmanaged step: $step") + } + } + +// val isLastFrame: Boolean +// get() { return this.currentFrame == numberOfFramesForCurrentStep - 1 } val shouldShowAdditionalFrame: Boolean get() { @@ -325,12 +347,16 @@ class ReplayerConfiguration(var handHistory: HandHistory) { } fun lastActionBeforeStreet(street: Street): ComputedAction? { - this.steps.forEachIndexed { index, handStep -> - if (handStep == street && index > 0) { - return this.steps[index - 1] as ComputedAction + var computedAction: ComputedAction? = null + for (step in this.steps) { + if (step is ComputedAction) { + computedAction = step + } + if (step == street) { + break } } - return null + return computedAction } fun next() { @@ -352,18 +378,19 @@ class ReplayerConfiguration(var handHistory: HandHistory) { private val lastActionAtStep: ComputedAction? get() { - return when (val step = this.steps[stepIndex]) { + when (val step = this.currentStep) { is ComputedAction -> { - step + return step } - is Street -> { - if (stepIndex > 0) { - this.steps[stepIndex - 1] as ComputedAction? - } else { - null + else -> { + (0 until stepIndex).reversed().forEach { i -> + val hs = this.steps[i] + if (hs is ComputedAction) { + return hs + } } + return null } - else -> throw PAIllegalStateException("unmanaged step: $step") } } @@ -391,15 +418,21 @@ class ReplayerConfiguration(var handHistory: HandHistory) { this.currentFrame += 1 } - fun animatedChipCircle(i: Int): Circle { + fun animatedChipCircleFromPot(i: Int): Circle { + return this.animatedChipCircle(this.potChipCircle, this.chipCircle(i)) + } + + fun animatedChipCircleToPot(i: Int): Circle { + return this.animatedChipCircle(this.chipCircle(i), this.potChipCircle) + } + + private fun animatedChipCircle(origin: Circle, destination: Circle): Circle { - val pCircle = this.chipCircle(i) - val potCircle = this.potChipCircle val completion = (this.currentFrame + 1).toFloat() / this.numberOfFramesForCurrentStep.toFloat() - val x = pCircle.x + (potCircle.x - pCircle.x) * completion - val y = pCircle.y + (potCircle.y - pCircle.y) * completion - val radius = pCircle.radius + (potCircle.radius - pCircle.radius) * completion // not very useful as radius are the same + val x = origin.x + (destination.x - origin.x) * completion + val y = origin.y + (destination.y - origin.y) * completion + val radius = origin.radius + (destination.radius - origin.radius) * completion // not very useful as radius are the same return Circle(x, y, radius) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt index f7f65e5a..6fdbff69 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt @@ -5,13 +5,13 @@ import android.graphics.* import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import net.pokeranalytics.android.R -import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction import net.pokeranalytics.android.util.RANDOM_PLAYER import net.pokeranalytics.android.util.extensions.formatted +import timber.log.Timber data class ChipColor(val fillColor: Int, val borderColor: Int) { companion object { @@ -106,20 +106,12 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { initializeTable(config, canvas, context) val step = config.currentStep - var computedAction: ComputedAction? = null - val street = when (step) { - is Street -> step - is ComputedAction -> { - computedAction = step - step.street - } - else -> throw PAIllegalStateException("Step unmanaged: $step") - } + val street = step.street + + val computedAction = step as? ComputedAction? // draw pot drawPot(street, computedAction, config, canvas, context) -// val potAction = computedAction ?: config.lastActionBeforeStreet(street) -// potAction?.let { drawPot(potAction, config, canvas, context) } // draw board drawBoardCards(street, config, canvas, context) @@ -159,45 +151,65 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { private fun drawPlayerChips(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { when (config.currentStep) { - is Street -> { // animate chips - if (!config.isLastFrame) { - lastCommitedAmount(i, config)?.let { amount -> - val color = colorForAmount(amount) - val circle = config.animatedChipCircle(i) - drawChipCircle(circle, color, canvas, context) + is Street -> { + when (config.frameType) { + ReplayerConfiguration.FrameType.STATE -> {} + ReplayerConfiguration.FrameType.GATHER_ANIMATION -> { + lastCommittedAmount(i, config)?.let { amount -> + val color = colorForAmount(amount) + val circle = config.animatedChipCircleToPot(i) + drawChipCircle(circle, color, canvas, context) + } + } + ReplayerConfiguration.FrameType.DISTRIBUTION_ANIMATION -> { + Timber.d("won pots = ${config.handHistory.winnerPots}") + val winnerPots = config.handHistory.winnerPots.firstOrNull { it.position == i } + winnerPots?.let { pot -> + val color = colorForAmount(pot.amount) + val circle = config.animatedChipCircleFromPot(i) + drawChipCircle(circle, color, canvas, context) + } } } } is ComputedAction -> { drawChipForAction(i, config, canvas, context) } + +// is HandStep.GatherChips -> { +// lastCommittedAmount(i, config)?.let { amount -> +// val color = colorForAmount(amount) +// val circle = config.animatedChipCircleToPot(i) +// drawChipCircle(circle, color, canvas, context) +// } +// } +// is HandStep.DistributeChips -> { +// config.handHistory.winnerPots.firstOrNull { it.position == i }?.let { pot -> +// val color = colorForAmount(pot.amount) +// val circle = config.animatedChipCircleFromPot(i) +// drawChipCircle(circle, color, canvas, context) +// } +// } +// is Street -> { // animate chips +// if (!config.isLastFrame) { +// lastCommittedAmount(i, config)?.let { amount -> +// val color = colorForAmount(amount) +// val circle = config.animatedChipCircle(i) +// drawChipCircle(circle, color, canvas, context) +// } +// } +// } } } private fun drawChipForAction(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { - lastCommitedAmount(i, config)?.let { amount -> + lastCommittedAmount(i, config)?.let { amount -> drawChip(amount, i, config, canvas, context) } - -// config.lastChipCommittingActionOfPlayer(i)?.let { action -> -// when { -// action.action.type?.isSignificant == true -> { -// action.action.amount?.let { amount -> -// drawChip(amount, action.positionIndex, config, canvas, context) -// } -// } -// action.action.type?.isCall == true -> { -// action.getStreetLastSignificantAction()?.action?.amount?.let { amount -> -// drawChip(amount, action.positionIndex, config, canvas, context) -// } -// } -// else -> {} -// } -// } } - private fun lastCommitedAmount(i: Int, config: ReplayerConfiguration): Double? { + private fun lastCommittedAmount(i: Int, config: ReplayerConfiguration): Double? { var committingAction = config.lastChipCommittingActionOfPlayer(i) if (committingAction?.action?.type?.isCall == true) { committingAction = committingAction.getStreetLastSignificantAction() @@ -420,13 +432,11 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { private fun drawBoardCards(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) { // when the step is the street, we wait for the last frame to display the board - if ((config.currentStep == street && config.isLastFrame) || config.currentStep != street) { - - val cards = config.handHistory.cardsForStreet(street) - config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF -> - drawCard(cards[index], rectF, config, canvas, context) - } - +// if ((config.currentStep == street && config.isLastFrame) || config.currentStep != street) { +// } + val cards = config.handHistory.cardsForStreet(street) + config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF -> + drawCard(cards[index], rectF, config, canvas, context) } }