From dd7a2d557504212e5dd6c20bdc7dcd50bb3f07f2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 12 Jun 2020 11:27:59 +0200 Subject: [PATCH] Adds animation when chip goes into the pot --- .../replayer/ReplayerConfiguration.kt | 54 ++++++++++++++++--- .../handhistory/replayer/ReplayerView.kt | 15 +++++- .../handhistory/replayer/TableDrawer.kt | 40 +++++++++++--- 3 files changed, 95 insertions(+), 14 deletions(-) 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 25203126..0c7f5aaa 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,6 +11,30 @@ import kotlin.math.max class ReplayerConfiguration(var handHistory: HandHistory) { + private val animationFramesPerSecond = 50 + val animationRate: Long + get() { return 1000L / this.animationFramesPerSecond} + private val animationDuration = 200L + + private val framesForStreetAnimation: Int + get() { return (animationDuration / animationRate).toInt() } + + private val numberOfFramesForCurrentStep: Int + get() { + return when (val step = this.steps[this.stepIndex]) { + is Street -> framesForStreetAnimation + 1 + is ComputedAction -> 1 + else -> throw PAIllegalStateException("unmanaged step: $step") + } + } + + private var currentFrame = 0 + + val shouldShowAdditionalFrame: Boolean + get() { + return this.currentFrame < this.numberOfFramesForCurrentStep + } + var actionList: ActionList = ActionList(null) private set @@ -19,6 +43,13 @@ class ReplayerConfiguration(var handHistory: HandHistory) { private var lastBlindIndex: Int = 0 private var stepIndex: Int = 0 + set(value) { + val backwards = value < field + field = value + + // if we go backwards we don't want to perform an animate, otherwise we want + this.currentFrame = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0 + } init { @@ -316,11 +347,6 @@ class ReplayerConfiguration(var handHistory: HandHistory) { return this.steps[this.stepIndex] } -// val stepsToDraw: List -// get() { -// return this.steps.take(this.stepIndex + 1) -// } - private val lastActionAtStep: ComputedAction? get() { return when (val step = this.steps[stepIndex]) { @@ -351,13 +377,29 @@ class ReplayerConfiguration(var handHistory: HandHistory) { return null } - fun lastSignificantActionOfPlayer(i: Int): ComputedAction? { + fun lastChipCommittingActionOfPlayer(i: Int): ComputedAction? { this.lastActionAtStep?.action?.index?.let { index -> return this.actionList.lastChipCommittingActionOfPlayer(i, index) } return null } + fun frameDrawn() { + this.currentFrame += 1 + } + + fun animatedChipCircle(i: Int): 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 + return Circle(x, y, radius) + } + } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt index 8c7ce512..4264ecac 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt @@ -2,6 +2,8 @@ package net.pokeranalytics.android.ui.modules.handhistory.replayer import android.content.Context import android.graphics.Canvas +import android.os.Handler +import android.os.Looper import android.util.AttributeSet import android.view.View import net.pokeranalytics.android.exceptions.PAIllegalStateException @@ -13,6 +15,12 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) lateinit var configuration: ReplayerConfiguration + private val animationHandler = Handler(Looper.getMainLooper()) + + private val timerRunnable: Runnable = Runnable { + refresh() + } + init { TableDrawer.configurePaints(context) @@ -22,7 +30,12 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) } fun refresh() { - this.invalidate() + + if (configuration.shouldShowAdditionalFrame) { + this.invalidate() + animationHandler.postDelayed(this.timerRunnable, this.configuration.animationRate) + } + } override fun onDraw(canvas: Canvas?) { 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 084b8098..1d6bd03a 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 @@ -67,6 +67,11 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { } fun drawTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { + drawTableItems(config, canvas, context) + config.frameDrawn() + } + + private fun drawTableItems(config: ReplayerConfiguration, canvas: Canvas, context: Context) { // base initializeTable(config, canvas, context) @@ -93,6 +98,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { val hh = config.handHistory for (i in 0 until hh.numberOfPlayers) { drawPlayerShapes(i, computedAction, config, canvas, context) + drawPlayerChips(i, config, canvas, context) } // show player cards @@ -115,8 +121,6 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { drawPositionAndStack(i, remainingStack, config, canvas) } - drawPlayerChips(i, config, canvas, context) - } /*** @@ -125,7 +129,23 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { */ private fun drawPlayerChips(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { - config.lastSignificantActionOfPlayer(i)?.let { action -> + when (config.currentStep) { + is Street -> { // animate chips + if (config.lastChipCommittingActionOfPlayer(i) != null) { + val circle = config.animatedChipCircle(i) + drawChipCircle(circle, canvas, context) + } + } + is ComputedAction -> { + drawChipForAction(i, config, canvas, context) + } + } + + } + + private fun drawChipForAction(i: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + + config.lastChipCommittingActionOfPlayer(i)?.let { action -> when { action.action.type?.isSignificant == true -> { action.action.amount?.let { amount -> @@ -182,6 +202,16 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { private fun drawChip(amount: Double, chipText: ReplayerConfiguration.TextPoint, chipCircle: ReplayerConfiguration.Circle, canvas: Canvas, context: Context) { + drawChipCircle(chipCircle, canvas, context) + + this.textPaint.textSize = chipText.fontSize + this.textPaint.color = context.getColor(R.color.white) + canvas.drawText(amount.formatted, chipText.x, chipText.y, this.textPaint) + + } + + private fun drawChipCircle(chipCircle: ReplayerConfiguration.Circle, canvas: Canvas, context: Context) { + this.fillPaint.color = context.getColor(R.color.green) canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius, this.fillPaint) this.chipBorderPaint.color = context.getColor(R.color.white) @@ -191,10 +221,6 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { chipBorderPaint.pathEffect = DashPathEffect(floatArrayOf(chipCircle.radius * 0.6f, chipCircle.radius * 0.44f), 0f) canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius - chipBorderStrokeWidth / 2, this.chipBorderPaint) - this.textPaint.textSize = chipText.fontSize - this.textPaint.color = context.getColor(R.color.white) - canvas.drawText(amount.formatted, chipText.x, chipText.y, this.textPaint) - } private fun drawCards(playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) {