Make the code for pot distribution animation

hh
Laurent 5 years ago
parent 4464ae54a3
commit 2e73896659
  1. 2
      app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt
  2. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ComputedAction.kt
  3. 17
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/HandStep.kt
  4. 79
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt
  5. 84
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt

@ -13,6 +13,8 @@ enum class Street : HandStep {
RIVER, RIVER,
SUMMARY; SUMMARY;
override val street: Street = this
val totalBoardCards: Int val totalBoardCards: Int
get() { get() {
return when (this) { return when (this) {

@ -300,7 +300,7 @@ class ComputedAction(var manager: ActionManager,
/*** /***
* Shortcut to return the action street * Shortcut to return the action street
*/ */
val street: Street override val street: Street
get() { return this.action.street } get() { return this.action.street }
override val viewType: Int = HandRowType.ACTION.ordinal override val viewType: Int = HandRowType.ACTION.ordinal

@ -6,11 +6,23 @@ import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.realm.handhistory.HandHistory
import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList
interface HandStep { 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 { companion object {
@ -27,6 +39,7 @@ interface HandStep {
for (action in streetActions) { for (action in streetActions) {
steps.add(action) steps.add(action)
} }
} }
return steps return steps
} }

@ -11,27 +11,49 @@ import kotlin.math.max
class ReplayerConfiguration(var handHistory: HandHistory) { class ReplayerConfiguration(var handHistory: HandHistory) {
enum class FrameType {
STATE,
GATHER_ANIMATION,
DISTRIBUTION_ANIMATION
}
private val animationFramesPerSecond = 60 private val animationFramesPerSecond = 60
val animationRate: Long val animationRate: Long
get() { return 1000L / this.animationFramesPerSecond} get() { return 1000L / this.animationFramesPerSecond}
private val animationDuration = 200L private val animationDuration = 200L
private val framesForStreetAnimation: Int private val framesForChipsAnimation: Int
get() { return (animationDuration / animationRate).toInt() } get() { return (animationDuration / animationRate).toInt() }
private val numberOfFramesForCurrentStep: Int private val numberOfFramesForCurrentStep: Int
get() { get() {
return when (val step = this.steps[this.stepIndex]) { return when (val step = this.currentStep) {
is Street -> framesForStreetAnimation + 1
is ComputedAction -> 1 is ComputedAction -> 1
Street.SUMMARY -> 1 + 2 * framesForChipsAnimation // 2 animations
is Street -> 1 + framesForChipsAnimation
else -> throw PAIllegalStateException("unmanaged step: $step") else -> throw PAIllegalStateException("unmanaged step: $step")
} }
} }
private var currentFrame = 0 private var currentFrame = 0
val isLastFrame: Boolean val frameType: FrameType
get() { return this.currentFrame == numberOfFramesForCurrentStep - 1 } 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 val shouldShowAdditionalFrame: Boolean
get() { get() {
@ -325,12 +347,16 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
} }
fun lastActionBeforeStreet(street: Street): ComputedAction? { fun lastActionBeforeStreet(street: Street): ComputedAction? {
this.steps.forEachIndexed { index, handStep -> var computedAction: ComputedAction? = null
if (handStep == street && index > 0) { for (step in this.steps) {
return this.steps[index - 1] as ComputedAction if (step is ComputedAction) {
computedAction = step
} }
if (step == street) {
break
} }
return null }
return computedAction
} }
fun next() { fun next() {
@ -352,18 +378,19 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
private val lastActionAtStep: ComputedAction? private val lastActionAtStep: ComputedAction?
get() { get() {
return when (val step = this.steps[stepIndex]) { when (val step = this.currentStep) {
is ComputedAction -> { is ComputedAction -> {
step return step
} }
is Street -> { else -> {
if (stepIndex > 0) { (0 until stepIndex).reversed().forEach { i ->
this.steps[stepIndex - 1] as ComputedAction? val hs = this.steps[i]
} else { if (hs is ComputedAction) {
null return hs
} }
} }
else -> throw PAIllegalStateException("unmanaged step: $step") return null
}
} }
} }
@ -391,15 +418,21 @@ class ReplayerConfiguration(var handHistory: HandHistory) {
this.currentFrame += 1 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 completion = (this.currentFrame + 1).toFloat() / this.numberOfFramesForCurrentStep.toFloat()
val x = pCircle.x + (potCircle.x - pCircle.x) * completion val x = origin.x + (destination.x - origin.x) * completion
val y = pCircle.y + (potCircle.y - pCircle.y) * completion val y = origin.y + (destination.y - origin.y) * completion
val radius = pCircle.radius + (potCircle.radius - pCircle.radius) * completion // not very useful as radius are the same val radius = origin.radius + (destination.radius - origin.radius) * completion // not very useful as radius are the same
return Circle(x, y, radius) return Circle(x, y, radius)
} }

@ -5,13 +5,13 @@ import android.graphics.*
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import net.pokeranalytics.android.R import net.pokeranalytics.android.R
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Position
import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.handhistory.Street
import net.pokeranalytics.android.model.realm.handhistory.Card import net.pokeranalytics.android.model.realm.handhistory.Card
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import net.pokeranalytics.android.util.RANDOM_PLAYER import net.pokeranalytics.android.util.RANDOM_PLAYER
import net.pokeranalytics.android.util.extensions.formatted import net.pokeranalytics.android.util.extensions.formatted
import timber.log.Timber
data class ChipColor(val fillColor: Int, val borderColor: Int) { data class ChipColor(val fillColor: Int, val borderColor: Int) {
companion object { companion object {
@ -106,20 +106,12 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
initializeTable(config, canvas, context) initializeTable(config, canvas, context)
val step = config.currentStep val step = config.currentStep
var computedAction: ComputedAction? = null val street = step.street
val street = when (step) {
is Street -> step val computedAction = step as? ComputedAction?
is ComputedAction -> {
computedAction = step
step.street
}
else -> throw PAIllegalStateException("Step unmanaged: $step")
}
// draw pot // draw pot
drawPot(street, computedAction, config, canvas, context) drawPot(street, computedAction, config, canvas, context)
// val potAction = computedAction ?: config.lastActionBeforeStreet(street)
// potAction?.let { drawPot(potAction, config, canvas, context) }
// draw board // draw board
drawBoardCards(street, config, canvas, context) 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) { private fun drawPlayerChips(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
when (config.currentStep) { when (config.currentStep) {
is Street -> { // animate chips is Street -> {
if (!config.isLastFrame) { when (config.frameType) {
lastCommitedAmount(i, config)?.let { amount -> ReplayerConfiguration.FrameType.STATE -> {}
ReplayerConfiguration.FrameType.GATHER_ANIMATION -> {
lastCommittedAmount(i, config)?.let { amount ->
val color = colorForAmount(amount) val color = colorForAmount(amount)
val circle = config.animatedChipCircle(i) val circle = config.animatedChipCircleToPot(i)
drawChipCircle(circle, color, canvas, context) 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 ComputedAction -> {
private fun drawChipForAction(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { drawChipForAction(i, config, canvas, context)
lastCommitedAmount(i, config)?.let { amount ->
drawChip(amount, i, config, canvas, context)
} }
// config.lastChipCommittingActionOfPlayer(i)?.let { action -> // is HandStep.GatherChips -> {
// when { // lastCommittedAmount(i, config)?.let { amount ->
// action.action.type?.isSignificant == true -> { // val color = colorForAmount(amount)
// action.action.amount?.let { amount -> // val circle = config.animatedChipCircleToPot(i)
// drawChip(amount, action.positionIndex, config, canvas, context) // drawChipCircle(circle, color, canvas, context)
// } // }
// } // }
// action.action.type?.isCall == true -> { // is HandStep.DistributeChips -> {
// action.getStreetLastSignificantAction()?.action?.amount?.let { amount -> // config.handHistory.winnerPots.firstOrNull { it.position == i }?.let { pot ->
// drawChip(amount, action.positionIndex, config, canvas, context) // val color = colorForAmount(pot.amount)
// val circle = config.animatedChipCircleFromPot(i)
// drawChipCircle(circle, color, canvas, context)
// } // }
// } // }
// else -> {} // 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) {
lastCommittedAmount(i, config)?.let { amount ->
drawChip(amount, i, config, canvas, context)
}
} }
private fun lastCommitedAmount(i: Int, config: ReplayerConfiguration): Double? { private fun lastCommittedAmount(i: Int, config: ReplayerConfiguration): Double? {
var committingAction = config.lastChipCommittingActionOfPlayer(i) var committingAction = config.lastChipCommittingActionOfPlayer(i)
if (committingAction?.action?.type?.isCall == true) { if (committingAction?.action?.type?.isCall == true) {
committingAction = committingAction.getStreetLastSignificantAction() committingAction = committingAction.getStreetLastSignificantAction()
@ -420,8 +432,8 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
private fun drawBoardCards(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) { 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 // 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) { // if ((config.currentStep == street && config.isLastFrame) || config.currentStep != street) {
// }
val cards = config.handHistory.cardsForStreet(street) val cards = config.handHistory.cardsForStreet(street)
config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF -> config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF ->
drawCard(cards[index], rectF, config, canvas, context) drawCard(cards[index], rectF, config, canvas, context)
@ -429,8 +441,6 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
} }
}
private fun drawPot(street: Street, computedAction: ComputedAction?, config: ReplayerConfiguration, canvas: Canvas, context: Context) { private fun drawPot(street: Street, computedAction: ComputedAction?, config: ReplayerConfiguration, canvas: Canvas, context: Context) {
val pot = config.actionList.potSizeForStreet(street) val pot = config.actionList.potSizeForStreet(street)

Loading…
Cancel
Save