From d2fd534964ec88257ee87e8b562eceb6d035ddbd Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 22 Sep 2021 14:02:20 +0800 Subject: [PATCH] update transform animation --- .../src/main/java/forge/game/card/Card.java | 5 + .../main/java/forge/game/card/CardView.java | 8 + .../forge/trackable/TrackableProperty.java | 1 + .../src/forge/screens/match/MatchScreen.java | 1 + .../screens/match/views/VCardDisplayArea.java | 1 + .../src/forge/toolbox/FCardPanel.java | 179 ++++++------------ 6 files changed, 73 insertions(+), 122 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 3252b9966fd..7026df19366 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -447,6 +447,10 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return setState(state, updateView, false); } public boolean setState(final CardStateName state, boolean updateView, boolean forceUpdate) { + boolean rollback = state == CardStateName.Original + && (currentStateName == CardStateName.Flipped || currentStateName == CardStateName.Transformed); + boolean transform = state == CardStateName.Flipped || state == CardStateName.Transformed || state == CardStateName.Meld; + boolean updateNeedsTransform = transform || rollback; // faceDown has higher priority over clone states // while text change states doesn't apply while the card is faceDown if (state != CardStateName.FaceDown) { @@ -487,6 +491,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { if (updateView) { view.updateState(this); + view.updateNeedsTransformAnimation(transform); final Game game = getGame(); if (game != null) { diff --git a/forge-game/src/main/java/forge/game/card/CardView.java b/forge-game/src/main/java/forge/game/card/CardView.java index ac9739a7e02..60ee88385c6 100644 --- a/forge-game/src/main/java/forge/game/card/CardView.java +++ b/forge-game/src/main/java/forge/game/card/CardView.java @@ -830,6 +830,14 @@ public class CardView extends GameEntityView { set(TrackableProperty.HasBackSide, hasBackSide); set(TrackableProperty.BackSideName, stateName); } + public boolean needsTransformAnimation() { + if (get(TrackableProperty.NeedsTransformAnimation) == null) + return false; + return get(TrackableProperty.NeedsTransformAnimation); + } + public void updateNeedsTransformAnimation(boolean value) { + set(TrackableProperty.NeedsTransformAnimation, value); + } void updateState(Card c) { updateName(c); updateZoneText(c); diff --git a/forge-game/src/main/java/forge/trackable/TrackableProperty.java b/forge-game/src/main/java/forge/trackable/TrackableProperty.java index 1fe0e5074cb..0545b373de9 100644 --- a/forge-game/src/main/java/forge/trackable/TrackableProperty.java +++ b/forge-game/src/main/java/forge/trackable/TrackableProperty.java @@ -80,6 +80,7 @@ public enum TrackableProperty { ExiledWith(TrackableTypes.CardViewType), WasDestroyed(TrackableTypes.BooleanType), CrackOverlay(TrackableTypes.IntegerType), + NeedsTransformAnimation(TrackableTypes.BooleanType), ImprintedCards(TrackableTypes.CardViewCollectionType), HauntedBy(TrackableTypes.CardViewCollectionType), diff --git a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java index 39974d71288..fed91e8ba1c 100644 --- a/forge-gui-mobile/src/forge/screens/match/MatchScreen.java +++ b/forge-gui-mobile/src/forge/screens/match/MatchScreen.java @@ -572,6 +572,7 @@ public class MatchScreen extends FScreen { } else { //ensure card not on battlefield is reset such that it no longer thinks it's on the battlefield pnl.setTapped(false); + pnl.setNeedsTransform(false); pnl.getAttachedPanels().clear(); pnl.setAttachedToPanel(null); pnl.setPrevPanelInStack(null); diff --git a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java index 53797b22aff..6b9561772a4 100644 --- a/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java +++ b/forge-gui-mobile/src/forge/screens/match/views/VCardDisplayArea.java @@ -283,6 +283,7 @@ public abstract class VCardDisplayArea extends VDisplayArea implements ActivateH public void updateCard(final CardView card) { setTapped(card.isTapped()); + setNeedsTransform(card.needsTransformAnimation()); attachedPanels.clear(); diff --git a/forge-gui-mobile/src/forge/toolbox/FCardPanel.java b/forge-gui-mobile/src/forge/toolbox/FCardPanel.java index a6016a56ba4..34976bc7785 100644 --- a/forge-gui-mobile/src/forge/toolbox/FCardPanel.java +++ b/forge-gui-mobile/src/forge/toolbox/FCardPanel.java @@ -23,12 +23,11 @@ public class FCardPanel extends FDisplayObject { private boolean tapped; private boolean highlighted; private boolean wasTapped; - private boolean wasTransformed; + private boolean needsTransform; CardTapAnimation tapAnimation; CardUnTapAnimation untapAnimation; CardDestroyedAnimation destroyedAnimation; CardTransformAnimation transformAnimation; - CardRollbackAnimation rollbackAnimation; public FCardPanel() { this(null); @@ -39,7 +38,6 @@ public class FCardPanel extends FDisplayObject { untapAnimation = new CardUnTapAnimation(); destroyedAnimation = new CardDestroyedAnimation(); transformAnimation = new CardTransformAnimation(); - rollbackAnimation = new CardRollbackAnimation(); } public CardView getCard() { @@ -62,6 +60,9 @@ public class FCardPanel extends FDisplayObject { public void setTapped(final boolean tapped0) { tapped = tapped0; } + public void setNeedsTransform(final boolean needsTransform0) { + needsTransform = needsTransform0; + } protected float getTappedAngle() { return -90; @@ -95,8 +96,8 @@ public class FCardPanel extends FDisplayObject { return CardStackPosition.Top; } - private class CardRollbackAnimation extends ForgeAnimation { - private static final float DURATION = 0.12f; + private class CardTransformAnimation extends ForgeAnimation { + private static final float DURATION = 0.14f; private float progress = 0; private boolean finished; @@ -106,60 +107,27 @@ public class FCardPanel extends FDisplayObject { percentage = 0; } else if (percentage > 1) { percentage = 1; - wasTransformed = false; + needsTransform = false; + card.updateNeedsTransformAnimation(false); + progress = 0; } float mod = percentage; - float x2 = x + (w - (w*mod))/2; - float w2 = w*mod; - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - CardRenderer.drawCardWithOverlays(g, card, x2, y, w2, h, getStackPosition()); - if (tapped) { - g.endTransform(); - } - } - - @Override - protected boolean advance(float dt) { - progress += dt; - return progress < DURATION; - } - - @Override - protected void onEnd(boolean endingAll) { - finished = true; - } - } - private class CardTransformAnimation extends ForgeAnimation { - private static final float DURATION = 0.12f; - private float progress = 0; - private boolean finished; - - private void drawCard(Graphics g, CardView card, float x, float y, float w, float h, float edgeOffset) { - float percentage = progress / DURATION; - if (percentage < 0) { - percentage = 0; - } else if (percentage > 1) { - percentage = 1; - wasTransformed = true; - } - float mod = card.hasAlternateState() ? percentage : 1f; float y2 = y + (h - (h*mod))/2; float x2 = x + (w - (w*mod))/2; float w2 = w*mod; float h2 = h*mod; - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - if (card.getCurrentState().getState() == CardStateName.Transformed || card.getCurrentState().getState() == CardStateName.Flipped) + if (card.getCurrentState().getState() == CardStateName.Original && needsTransform) { + //rollback CardRenderer.drawCardWithOverlays(g, card, x2, y, w2, h, getStackPosition()); - else if (card.getCurrentState().getState() == CardStateName.Meld) - CardRenderer.drawCardWithOverlays(g, card, x2, y2, w2, h2, getStackPosition()); - else //default - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - if (tapped) { - g.endTransform(); + } else if (card.hasAlternateState() && (card.getCurrentState().getState() == CardStateName.Flipped + || card.getCurrentState().getState() == CardStateName.Transformed || card.getCurrentState().getState() == CardStateName.Meld) && needsTransform) { + //transform + if (card.getCurrentState().getState() == CardStateName.Transformed || card.getCurrentState().getState() == CardStateName.Flipped) + CardRenderer.drawCardWithOverlays(g, card, x2, y, w2, h, getStackPosition()); + else if (card.getCurrentState().getState() == CardStateName.Meld) + CardRenderer.drawCardWithOverlays(g, card, x2, y2, w2, h2, getStackPosition()); + } else { + CardRenderer.drawCardWithOverlays(g, card, x, y2, w, h2, getStackPosition()); } } @@ -225,15 +193,12 @@ public class FCardPanel extends FDisplayObject { percentage = 0; } else if (percentage > 1) { percentage = 1; + wasTapped = false; } float angle = -90 + (percentage*90); - if (wasTapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, angle); - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - g.endTransform(); - } else { - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - } + g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, angle); + CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + g.endTransform(); } @Override @@ -249,7 +214,7 @@ public class FCardPanel extends FDisplayObject { } private class CardTapAnimation extends ForgeAnimation { - private static final float DURATION = 0.18f; + private static final float DURATION = 0.14f; private float progress = 0; private boolean finished; @@ -297,13 +262,7 @@ public class FCardPanel extends FDisplayObject { if (!animate || isGameFast || MatchController.instance.getGameView().isMatchOver()) { //don't animate if game is fast or match is over - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - if (tapped) { - g.endTransform(); - } + rotateTransform(g, x, y, w, h, edgeOffset, false); } else { //card destroy animation if (card.wasDestroyed()) { @@ -312,61 +271,13 @@ public class FCardPanel extends FDisplayObject { destroyedAnimation.start(); destroyedAnimation.drawCard(g, card, x, y, w, h, edgeOffset); } else { - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - if (tapped) { - g.endTransform(); - } - } - } - return; - } - //card transform animation - if (card.getCurrentState().getState() == CardStateName.Original && wasTransformed) { - //reset transform - if (transformAnimation != null) - transformAnimation.progress = 0; - if (rollbackAnimation != null) { - if (rollbackAnimation.progress < 1) { - rollbackAnimation.start(); - rollbackAnimation.drawCard(g, card, x, y, w, h, edgeOffset); - } else { - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - if (tapped) { - g.endTransform(); - } - } - } - return; - } - if (card.hasAlternateState() && (card.getCurrentState().getState() == CardStateName.Flipped - || card.getCurrentState().getState() == CardStateName.Transformed || card.getCurrentState().getState() == CardStateName.Meld) && !wasTransformed) { - //reset rollback - if (rollbackAnimation != null) - rollbackAnimation.progress = 0; - if (transformAnimation != null) { - if (transformAnimation.progress < 1) { - transformAnimation.start(); - transformAnimation.drawCard(g, card, x, y, w, h, edgeOffset); - } else { - if (tapped) { - g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - } - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); - if (tapped) { - g.endTransform(); - } + rotateTransform(g, x, y, w, h, edgeOffset, animate); } } return; } //tap-untap animation - if (tapped) { + if (tapped && !wasTapped) { //reset untapAnimation if (untapAnimation != null) { untapAnimation.progress = 0; @@ -378,11 +289,16 @@ public class FCardPanel extends FDisplayObject { tapAnimation.drawCard(g, card, x, y, w, h, w / 2f, getTappedAngle()); } else { g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + if (needsTransform) { + transformAnimation.start(); + transformAnimation.drawCard(g, card, x, y, w, h, edgeOffset); + } else { + CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + } g.endTransform(); } } - } else { + } else if (!tapped && wasTapped) { //reset tapAnimation if (tapAnimation != null) { tapAnimation.progress = 0; @@ -393,14 +309,33 @@ public class FCardPanel extends FDisplayObject { untapAnimation.start(); untapAnimation.drawCard(g, card, x, y, w, h, edgeOffset); } else { - wasTapped = false; - CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + if (needsTransform) { + transformAnimation.start(); + transformAnimation.drawCard(g, card, x, y, w, h, edgeOffset); + } else { + CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + } } } + } else { + rotateTransform(g, x, y, w, h, edgeOffset, animate); } } } - + void rotateTransform(Graphics g, float x, float y, float w, float h, float edgeOffset, boolean animate) { + if (tapped) { + g.startRotateTransform(x + edgeOffset, y + h - edgeOffset, getTappedAngle()); + } + if (needsTransform && animate) { + transformAnimation.start(); + transformAnimation.drawCard(g, card, x, y, w, h, edgeOffset); + } else { + CardRenderer.drawCardWithOverlays(g, card, x, y, w, h, getStackPosition()); + } + if (tapped) { + g.endTransform(); + } + } public String toString() { return card == null ? "" : card.toString(); }